All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-08-22  2:09 ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm
  Cc: srv_heupstream, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, zhi.mao, yingjoe.chen, yt.shen, sean.wang,
	zhenbao.liu


change in v4:
modify some coding style and naming of variable to make code readable.

Zhi Mao (1):
  pwm: mediatek: add MT2712/MT7622 support

 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

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

* [PATCH v4 0/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-08-22  2:09 ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: john-Pj+rj9U5foFAfugRpC6u6w, Thierry Reding, Rob Herring,
	Mark Rutland, Matthias Brugger, linux-pwm-u79uwXL29TY76Z2rM5mHXA
  Cc: srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	zhi.mao-NuS5LvNUpcJWk0Htik3J/w,
	yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
	yt.shen-NuS5LvNUpcJWk0Htik3J/w, sean.wang-NuS5LvNUpcJWk0Htik3J/w,
	zhenbao.liu-NuS5LvNUpcJWk0Htik3J/w


change in v4:
modify some coding style and naming of variable to make code readable.

Zhi Mao (1):
  pwm: mediatek: add MT2712/MT7622 support

 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 0/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-08-22  2:09 ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: linux-arm-kernel


change in v4:
modify some coding style and naming of variable to make code readable.

Zhi Mao (1):
  pwm: mediatek: add MT2712/MT7622 support

 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-08-22  2:09 ` Zhi Mao
  (?)
@ 2017-08-22  2:09   ` Zhi Mao
  -1 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm
  Cc: srv_heupstream, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, zhi.mao, yingjoe.chen, yt.shen, sean.wang,
	zhenbao.liu

Add support to MT2712 and MT7622.
Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
add mtk_pwm_reg_offset array for pwm register offset.

Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 1d78ab1..ccd86e7 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/slab.h>
@@ -40,11 +41,19 @@ enum {
 	MTK_CLK_PWM3,
 	MTK_CLK_PWM4,
 	MTK_CLK_PWM5,
+	MTK_CLK_PWM6,
+	MTK_CLK_PWM7,
+	MTK_CLK_PWM8,
 	MTK_CLK_MAX,
 };
 
-static const char * const mtk_pwm_clk_name[] = {
-	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
+static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
+	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
+	"pwm8"
+};
+
+struct mtk_pwm_platform_data {
+	unsigned int num_pwms;
 };
 
 /**
@@ -57,6 +66,11 @@ struct mtk_pwm_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
 	struct clk *clks[MTK_CLK_MAX];
+	const struct mtk_pwm_platform_data *data;
+};
+
+static const unsigned int mtk_pwm_reg_offset[] = {
+	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
 };
 
 static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
@@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
 				unsigned int offset)
 {
-	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
+	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
 				  unsigned int num, unsigned int offset,
 				  u32 value)
 {
-	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
+	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	if (!pc)
 		return -ENOMEM;
 
+	pc->data = of_device_get_match_data(&pdev->dev);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pc->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(pc->regs))
 		return PTR_ERR(pc->regs);
 
-	for (i = 0; i < MTK_CLK_MAX; i++) {
+	for (i = 0; i < pc->data->num_pwms + 2; i++) {
 		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
-		if (IS_ERR(pc->clks[i]))
+		if (IS_ERR(pc->clks[i])) {
+			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
+				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
 			return PTR_ERR(pc->clks[i]);
+		}
 	}
 
 	platform_set_drvdata(pdev, pc);
@@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
-	pc->chip.npwm = 5;
+	pc->chip.npwm = pc->data->num_pwms;
 
 	ret = pwmchip_add(&pc->chip);
 	if (ret < 0) {
@@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 	return pwmchip_remove(&pc->chip);
 }
 
+static const struct mtk_pwm_platform_data mt2712_pwm_data = {
+	.num_pwms = 8,
+};
+
+static const struct mtk_pwm_platform_data mt7622_pwm_data = {
+	.num_pwms = 6,
+};
+
+static const struct mtk_pwm_platform_data mt7623_pwm_data = {
+	.num_pwms = 5,
+};
+
 static const struct of_device_id mtk_pwm_of_match[] = {
-	{ .compatible = "mediatek,mt7623-pwm" },
-	{ }
+	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
+	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
+	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
+	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
 
-- 
1.7.9.5

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-08-22  2:09   ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm
  Cc: srv_heupstream, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, zhi.mao, yingjoe.chen, yt.shen, sean.wang,
	zhenbao.liu

Add support to MT2712 and MT7622.
Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
add mtk_pwm_reg_offset array for pwm register offset.

Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 1d78ab1..ccd86e7 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/slab.h>
@@ -40,11 +41,19 @@ enum {
 	MTK_CLK_PWM3,
 	MTK_CLK_PWM4,
 	MTK_CLK_PWM5,
+	MTK_CLK_PWM6,
+	MTK_CLK_PWM7,
+	MTK_CLK_PWM8,
 	MTK_CLK_MAX,
 };
 
-static const char * const mtk_pwm_clk_name[] = {
-	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
+static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
+	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
+	"pwm8"
+};
+
+struct mtk_pwm_platform_data {
+	unsigned int num_pwms;
 };
 
 /**
@@ -57,6 +66,11 @@ struct mtk_pwm_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
 	struct clk *clks[MTK_CLK_MAX];
+	const struct mtk_pwm_platform_data *data;
+};
+
+static const unsigned int mtk_pwm_reg_offset[] = {
+	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
 };
 
 static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
@@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
 				unsigned int offset)
 {
-	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
+	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
 				  unsigned int num, unsigned int offset,
 				  u32 value)
 {
-	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
+	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	if (!pc)
 		return -ENOMEM;
 
+	pc->data = of_device_get_match_data(&pdev->dev);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pc->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(pc->regs))
 		return PTR_ERR(pc->regs);
 
-	for (i = 0; i < MTK_CLK_MAX; i++) {
+	for (i = 0; i < pc->data->num_pwms + 2; i++) {
 		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
-		if (IS_ERR(pc->clks[i]))
+		if (IS_ERR(pc->clks[i])) {
+			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
+				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
 			return PTR_ERR(pc->clks[i]);
+		}
 	}
 
 	platform_set_drvdata(pdev, pc);
@@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
-	pc->chip.npwm = 5;
+	pc->chip.npwm = pc->data->num_pwms;
 
 	ret = pwmchip_add(&pc->chip);
 	if (ret < 0) {
@@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 	return pwmchip_remove(&pc->chip);
 }
 
+static const struct mtk_pwm_platform_data mt2712_pwm_data = {
+	.num_pwms = 8,
+};
+
+static const struct mtk_pwm_platform_data mt7622_pwm_data = {
+	.num_pwms = 6,
+};
+
+static const struct mtk_pwm_platform_data mt7623_pwm_data = {
+	.num_pwms = 5,
+};
+
 static const struct of_device_id mtk_pwm_of_match[] = {
-	{ .compatible = "mediatek,mt7623-pwm" },
-	{ }
+	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
+	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
+	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
+	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
 
-- 
1.7.9.5

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-08-22  2:09   ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-08-22  2:09 UTC (permalink / raw)
  To: linux-arm-kernel

Add support to MT2712 and MT7622.
Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
add mtk_pwm_reg_offset array for pwm register offset.

Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 1d78ab1..ccd86e7 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/slab.h>
@@ -40,11 +41,19 @@ enum {
 	MTK_CLK_PWM3,
 	MTK_CLK_PWM4,
 	MTK_CLK_PWM5,
+	MTK_CLK_PWM6,
+	MTK_CLK_PWM7,
+	MTK_CLK_PWM8,
 	MTK_CLK_MAX,
 };
 
-static const char * const mtk_pwm_clk_name[] = {
-	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
+static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
+	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
+	"pwm8"
+};
+
+struct mtk_pwm_platform_data {
+	unsigned int num_pwms;
 };
 
 /**
@@ -57,6 +66,11 @@ struct mtk_pwm_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
 	struct clk *clks[MTK_CLK_MAX];
+	const struct mtk_pwm_platform_data *data;
+};
+
+static const unsigned int mtk_pwm_reg_offset[] = {
+	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
 };
 
 static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
@@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
 				unsigned int offset)
 {
-	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
+	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
 				  unsigned int num, unsigned int offset,
 				  u32 value)
 {
-	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
+	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
 }
 
 static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	if (!pc)
 		return -ENOMEM;
 
+	pc->data = of_device_get_match_data(&pdev->dev);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	pc->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(pc->regs))
 		return PTR_ERR(pc->regs);
 
-	for (i = 0; i < MTK_CLK_MAX; i++) {
+	for (i = 0; i < pc->data->num_pwms + 2; i++) {
 		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
-		if (IS_ERR(pc->clks[i]))
+		if (IS_ERR(pc->clks[i])) {
+			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
+				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
 			return PTR_ERR(pc->clks[i]);
+		}
 	}
 
 	platform_set_drvdata(pdev, pc);
@@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
-	pc->chip.npwm = 5;
+	pc->chip.npwm = pc->data->num_pwms;
 
 	ret = pwmchip_add(&pc->chip);
 	if (ret < 0) {
@@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 	return pwmchip_remove(&pc->chip);
 }
 
+static const struct mtk_pwm_platform_data mt2712_pwm_data = {
+	.num_pwms = 8,
+};
+
+static const struct mtk_pwm_platform_data mt7622_pwm_data = {
+	.num_pwms = 6,
+};
+
+static const struct mtk_pwm_platform_data mt7623_pwm_data = {
+	.num_pwms = 5,
+};
+
 static const struct of_device_id mtk_pwm_of_match[] = {
-	{ .compatible = "mediatek,mt7623-pwm" },
-	{ }
+	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
+	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
+	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
+	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
 
-- 
1.7.9.5

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-08-22  2:09   ` Zhi Mao
  (?)
@ 2017-09-20  8:48     ` Zhi Mao
  -1 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-09-20  8:48 UTC (permalink / raw)
  To: john, Thierry Reding
  Cc: Thierry Reding, Rob Herring, Mark Rutland, Matthias Brugger,
	linux-pwm, srv_heupstream, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, yingjoe.chen, yt.shen,
	sean.wang, zhenbao.liu

Hi Thierry,

Just a gentle ping on this issue.
Would you please have a review to this patch?

Regards,
Zhi


On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-09-20  8:48     ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-09-20  8:48 UTC (permalink / raw)
  To: john
  Cc: Thierry Reding, Rob Herring, Mark Rutland, Matthias Brugger,
	linux-pwm, srv_heupstream, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, yingjoe.chen, yt.shen,
	sean.wang, zhenbao.liu

Hi Thierry,

Just a gentle ping on this issue.
Would you please have a review to this patch?

Regards,
Zhi


On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-09-20  8:48     ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-09-20  8:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thierry,

Just a gentle ping on this issue.
Would you please have a review to this patch?

Regards,
Zhi


On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-09-20  8:48     ` Zhi Mao
  (?)
@ 2017-10-23  5:27       ` Zhi Mao
  -1 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23  5:27 UTC (permalink / raw)
  To: Thierry Reding
  Cc: zhi.mao, john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, srv_heupstream, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, yingjoe.chen,
	yt.shen, sean.wang, zhenbao.liu

Hi Thierry,

Just have a ping on this issue.

Regards,
Zhi

On Wed, 2017-09-20 at 16:48 +0800, Zhi Mao wrote:
> Hi Thierry,
> 
> Just a gentle ping on this issue.
> Would you please have a review to this patch?
> 
> Regards,
> Zhi
> 
> 
> On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23  5:27       ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23  5:27 UTC (permalink / raw)
  Cc: zhi.mao-NuS5LvNUpcJWk0Htik3J/w, john-Pj+rj9U5foFAfugRpC6u6w,
	Thierry Reding, Rob Herring, Mark Rutland, Matthias Brugger,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
	yt.shen-NuS5LvNUpcJWk0Htik3J/w, sean.wang-NuS5LvNUpcJWk0Htik3J/w,
	zhenbao.liu-NuS5LvNUpcJWk0Htik3J/w

Hi Thierry,

Just have a ping on this issue.

Regards,
Zhi

On Wed, 2017-09-20 at 16:48 +0800, Zhi Mao wrote:
> Hi Thierry,
> 
> Just a gentle ping on this issue.
> Would you please have a review to this patch?
> 
> Regards,
> Zhi
> 
> 
> On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> 


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23  5:27       ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23  5:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thierry,

Just have a ping on this issue.

Regards,
Zhi

On Wed, 2017-09-20 at 16:48 +0800, Zhi Mao wrote:
> Hi Thierry,
> 
> Just a gentle ping on this issue.
> Would you please have a review to this patch?
> 
> Regards,
> Zhi
> 
> 
> On Tue, 2017-08-22 at 10:09 +0800, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23  8:22     ` m18063
  0 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-23  8:22 UTC (permalink / raw)
  To: Zhi Mao, john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm
  Cc: zhenbao.liu, devicetree, srv_heupstream, sean.wang, linux-kernel,
	linux-mediatek, yt.shen, yingjoe.chen, linux-arm-kernel

Hi Zhi,

I have few comments regarding your patch. Please see them below.

Thanks,
Claudiu

On 22.08.2017 05:09, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
I think you can remove this member since you only use it to initialize chip.npwm,
in probe function, just before platform_set_drvdata().

	pc->chip.npwm = pc->data->pwm_nums;

	platform_set_drvdata(pdev, pc);
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
You forgot to check pc->data == NULL (in case device tree inputs are not provided)
and you may use here a stack allocated variable to store the number of PWMs returned
by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
any, you could get that information from chip.npwm.
You could also check here the number of PWMs returned via of_device_get_match_data()
to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
pwmchip_add() will fail).

> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23  8:22     ` m18063
  0 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-23  8:22 UTC (permalink / raw)
  To: Zhi Mao, john-Pj+rj9U5foFAfugRpC6u6w, Thierry Reding,
	Rob Herring, Mark Rutland, Matthias Brugger,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA
  Cc: zhenbao.liu-NuS5LvNUpcJWk0Htik3J/w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	sean.wang-NuS5LvNUpcJWk0Htik3J/w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	yt.shen-NuS5LvNUpcJWk0Htik3J/w,
	yingjoe.chen-NuS5LvNUpcJWk0Htik3J/w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Zhi,

I have few comments regarding your patch. Please see them below.

Thanks,
Claudiu

On 22.08.2017 05:09, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
I think you can remove this member since you only use it to initialize chip.npwm,
in probe function, just before platform_set_drvdata().

	pc->chip.npwm = pc->data->pwm_nums;

	platform_set_drvdata(pdev, pc);
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
You forgot to check pc->data == NULL (in case device tree inputs are not provided)
and you may use here a stack allocated variable to store the number of PWMs returned
by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
any, you could get that information from chip.npwm.
You could also check here the number of PWMs returned via of_device_get_match_data()
to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
pwmchip_add() will fail).

> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23  8:22     ` m18063
  0 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-23  8:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Zhi,

I have few comments regarding your patch. Please see them below.

Thanks,
Claudiu

On 22.08.2017 05:09, Zhi Mao wrote:
> Add support to MT2712 and MT7622.
> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> add mtk_pwm_reg_offset array for pwm register offset.
> 
> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> ---
>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> index 1d78ab1..ccd86e7 100644
> --- a/drivers/pwm/pwm-mediatek.c
> +++ b/drivers/pwm/pwm-mediatek.c
> @@ -16,6 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/clk.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pwm.h>
>  #include <linux/slab.h>
> @@ -40,11 +41,19 @@ enum {
>  	MTK_CLK_PWM3,
>  	MTK_CLK_PWM4,
>  	MTK_CLK_PWM5,
> +	MTK_CLK_PWM6,
> +	MTK_CLK_PWM7,
> +	MTK_CLK_PWM8,
>  	MTK_CLK_MAX,
>  };
>  
> -static const char * const mtk_pwm_clk_name[] = {
> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> +	"pwm8"
> +};
> +
> +struct mtk_pwm_platform_data {
> +	unsigned int num_pwms;
>  };
>  
>  /**
> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	struct clk *clks[MTK_CLK_MAX];
> +	const struct mtk_pwm_platform_data *data;
I think you can remove this member since you only use it to initialize chip.npwm,
in probe function, just before platform_set_drvdata().

	pc->chip.npwm = pc->data->pwm_nums;

	platform_set_drvdata(pdev, pc);
> +};
> +
> +static const unsigned int mtk_pwm_reg_offset[] = {
> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>  };
>  
>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>  				unsigned int offset)
>  {
> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>  				  unsigned int num, unsigned int offset,
>  				  u32 value)
>  {
> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>  }
>  
>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	if (!pc)
>  		return -ENOMEM;
>  
> +	pc->data = of_device_get_match_data(&pdev->dev);
You forgot to check pc->data == NULL (in case device tree inputs are not provided)
and you may use here a stack allocated variable to store the number of PWMs returned
by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
any, you could get that information from chip.npwm.
You could also check here the number of PWMs returned via of_device_get_match_data()
to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
pwmchip_add() will fail).

> +
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>  	if (IS_ERR(pc->regs))
>  		return PTR_ERR(pc->regs);
>  
> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> -		if (IS_ERR(pc->clks[i]))
> +		if (IS_ERR(pc->clks[i])) {
> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>  			return PTR_ERR(pc->clks[i]);
> +		}
>  	}
>  
>  	platform_set_drvdata(pdev, pc);
> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> -	pc->chip.npwm = 5;
> +	pc->chip.npwm = pc->data->num_pwms;
>  
>  	ret = pwmchip_add(&pc->chip);
>  	if (ret < 0) {
> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>  	return pwmchip_remove(&pc->chip);
>  }
>  
> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> +	.num_pwms = 8,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> +	.num_pwms = 6,
> +};
> +
> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> +	.num_pwms = 5,
> +};
> +
>  static const struct of_device_id mtk_pwm_of_match[] = {
> -	{ .compatible = "mediatek,mt7623-pwm" },
> -	{ }
> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> +	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>  
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-10-23  8:22     ` m18063
  (?)
@ 2017-10-23 11:13       ` Zhi Mao
  -1 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23 11:13 UTC (permalink / raw)
  To: m18063
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen, linux-arm-kernel

Hi Claudiu

please check the comments as below.

Regards
Zhi

On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> Hi Zhi,
> 
> I have few comments regarding your patch. Please see them below.
> 
> Thanks,
> Claudiu
> 
> On 22.08.2017 05:09, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> I think you can remove this member since you only use it to initialize chip.npwm,
> in probe function, just before platform_set_drvdata().
> 
> 	pc->chip.npwm = pc->data->pwm_nums;
> 
> 	platform_set_drvdata(pdev, pc);
Here, the member of "mtk_pwm_platform_data" is an extension interface of
pwm information for MTK SOC chips. At present, we use it to initialize
npwms, and maybe we will have more informations to use, in later. 
so, we want to keep it and make the interface more flexible. 

> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> and you may use here a stack allocated variable to store the number of PWMs returned
> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> any, you could get that information from chip.npwm.
> You could also check here the number of PWMs returned via of_device_get_match_data()
> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> pwmchip_add() will fail).
> 
Here, I will add the NULL pointer checking for "pc->data", and it will
be released, soon.

> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> > 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23 11:13       ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23 11:13 UTC (permalink / raw)
  To: m18063
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen

Hi Claudiu

please check the comments as below.

Regards
Zhi

On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> Hi Zhi,
> 
> I have few comments regarding your patch. Please see them below.
> 
> Thanks,
> Claudiu
> 
> On 22.08.2017 05:09, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> I think you can remove this member since you only use it to initialize chip.npwm,
> in probe function, just before platform_set_drvdata().
> 
> 	pc->chip.npwm = pc->data->pwm_nums;
> 
> 	platform_set_drvdata(pdev, pc);
Here, the member of "mtk_pwm_platform_data" is an extension interface of
pwm information for MTK SOC chips. At present, we use it to initialize
npwms, and maybe we will have more informations to use, in later. 
so, we want to keep it and make the interface more flexible. 

> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> and you may use here a stack allocated variable to store the number of PWMs returned
> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> any, you could get that information from chip.npwm.
> You could also check here the number of PWMs returned via of_device_get_match_data()
> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> pwmchip_add() will fail).
> 
Here, I will add the NULL pointer checking for "pc->data", and it will
be released, soon.

> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> > 

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-23 11:13       ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-23 11:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Claudiu

please check the comments as below.

Regards
Zhi

On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> Hi Zhi,
> 
> I have few comments regarding your patch. Please see them below.
> 
> Thanks,
> Claudiu
> 
> On 22.08.2017 05:09, Zhi Mao wrote:
> > Add support to MT2712 and MT7622.
> > Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> > add mtk_pwm_reg_offset array for pwm register offset.
> > 
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> >  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 42 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> > index 1d78ab1..ccd86e7 100644
> > --- a/drivers/pwm/pwm-mediatek.c
> > +++ b/drivers/pwm/pwm-mediatek.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/module.h>
> >  #include <linux/clk.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pwm.h>
> >  #include <linux/slab.h>
> > @@ -40,11 +41,19 @@ enum {
> >  	MTK_CLK_PWM3,
> >  	MTK_CLK_PWM4,
> >  	MTK_CLK_PWM5,
> > +	MTK_CLK_PWM6,
> > +	MTK_CLK_PWM7,
> > +	MTK_CLK_PWM8,
> >  	MTK_CLK_MAX,
> >  };
> >  
> > -static const char * const mtk_pwm_clk_name[] = {
> > -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> > +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> > +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> > +	"pwm8"
> > +};
> > +
> > +struct mtk_pwm_platform_data {
> > +	unsigned int num_pwms;
> >  };
> >  
> >  /**
> > @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >  	struct pwm_chip chip;
> >  	void __iomem *regs;
> >  	struct clk *clks[MTK_CLK_MAX];
> > +	const struct mtk_pwm_platform_data *data;
> I think you can remove this member since you only use it to initialize chip.npwm,
> in probe function, just before platform_set_drvdata().
> 
> 	pc->chip.npwm = pc->data->pwm_nums;
> 
> 	platform_set_drvdata(pdev, pc);
Here, the member of "mtk_pwm_platform_data" is an extension interface of
pwm information for MTK SOC chips. At present, we use it to initialize
npwms, and maybe we will have more informations to use, in later. 
so, we want to keep it and make the interface more flexible. 

> > +};
> > +
> > +static const unsigned int mtk_pwm_reg_offset[] = {
> > +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >  };
> >  
> >  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> > @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >  				unsigned int offset)
> >  {
> > -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> > +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >  				  unsigned int num, unsigned int offset,
> >  				  u32 value)
> >  {
> > -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> > +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >  }
> >  
> >  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> > @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	if (!pc)
> >  		return -ENOMEM;
> >  
> > +	pc->data = of_device_get_match_data(&pdev->dev);
> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> and you may use here a stack allocated variable to store the number of PWMs returned
> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> any, you could get that information from chip.npwm.
> You could also check here the number of PWMs returned via of_device_get_match_data()
> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> pwmchip_add() will fail).
> 
Here, I will add the NULL pointer checking for "pc->data", and it will
be released, soon.

> > +
> >  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >  	if (IS_ERR(pc->regs))
> >  		return PTR_ERR(pc->regs);
> >  
> > -	for (i = 0; i < MTK_CLK_MAX; i++) {
> > +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> > -		if (IS_ERR(pc->clks[i]))
> > +		if (IS_ERR(pc->clks[i])) {
> > +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> > +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >  			return PTR_ERR(pc->clks[i]);
> > +		}
> >  	}
> >  
> >  	platform_set_drvdata(pdev, pc);
> > @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >  	pc->chip.dev = &pdev->dev;
> >  	pc->chip.ops = &mtk_pwm_ops;
> >  	pc->chip.base = -1;
> > -	pc->chip.npwm = 5;
> > +	pc->chip.npwm = pc->data->num_pwms;
> >  
> >  	ret = pwmchip_add(&pc->chip);
> >  	if (ret < 0) {
> > @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >  	return pwmchip_remove(&pc->chip);
> >  }
> >  
> > +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> > +	.num_pwms = 8,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> > +	.num_pwms = 6,
> > +};
> > +
> > +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> > +	.num_pwms = 5,
> > +};
> > +
> >  static const struct of_device_id mtk_pwm_of_match[] = {
> > -	{ .compatible = "mediatek,mt7623-pwm" },
> > -	{ }
> > +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> > +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> > +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> > +	{ },
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >  
> > 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-10-23 11:13       ` Zhi Mao
  (?)
@ 2017-10-24 13:25         ` m18063
  -1 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-24 13:25 UTC (permalink / raw)
  To: Zhi Mao
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen, linux-arm-kernel

Hi Zhi,

Please see my answer below.

On 23.10.2017 14:13, Zhi Mao wrote:
> Hi Claudiu
> 
> please check the comments as below.
> 
> Regards
> Zhi
> 
> On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
>> Hi Zhi,
>>
>> I have few comments regarding your patch. Please see them below.
>>
>> Thanks,
>> Claudiu
>>
>> On 22.08.2017 05:09, Zhi Mao wrote:
>>> Add support to MT2712 and MT7622.
>>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
>>> add mtk_pwm_reg_offset array for pwm register offset.
>>>
>>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
>>> ---
>>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>>>  1 file changed, 42 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
>>> index 1d78ab1..ccd86e7 100644
>>> --- a/drivers/pwm/pwm-mediatek.c
>>> +++ b/drivers/pwm/pwm-mediatek.c
>>> @@ -16,6 +16,7 @@
>>>  #include <linux/module.h>
>>>  #include <linux/clk.h>
>>>  #include <linux/of.h>
>>> +#include <linux/of_device.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/pwm.h>
>>>  #include <linux/slab.h>
>>> @@ -40,11 +41,19 @@ enum {
>>>  	MTK_CLK_PWM3,
>>>  	MTK_CLK_PWM4,
>>>  	MTK_CLK_PWM5,
>>> +	MTK_CLK_PWM6,
>>> +	MTK_CLK_PWM7,
>>> +	MTK_CLK_PWM8,
>>>  	MTK_CLK_MAX,
>>>  };
>>>  
>>> -static const char * const mtk_pwm_clk_name[] = {
>>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
>>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
>>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
>>> +	"pwm8"
>>> +};
>>> +
>>> +struct mtk_pwm_platform_data {
>>> +	unsigned int num_pwms;
>>>  };
>>>  
>>>  /**
>>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>>>  	struct pwm_chip chip;
>>>  	void __iomem *regs;
>>>  	struct clk *clks[MTK_CLK_MAX];
>>> +	const struct mtk_pwm_platform_data *data;
>> I think you can remove this member since you only use it to initialize chip.npwm,
>> in probe function, just before platform_set_drvdata().
>>
>> 	pc->chip.npwm = pc->data->pwm_nums;
>>
>> 	platform_set_drvdata(pdev, pc);
> Here, the member of "mtk_pwm_platform_data" is an extension interface of
> pwm information for MTK SOC chips. At present, we use it to initialize
> npwms,

and maybe we will have more informations to use, in later. 

The use of *maybe* in here suggest me that this will not necessary happen.
Actually, what I wanted to emphasize is that, for the moment, you are keeping
same information in both driver private data structure and PWM framework data
structure. So, even if in future you will add more members to this data structure,
you will have the number of PWMs stored in both, your driver data structure
(via "struct mtk_pwm_platform_data *data" member) and PWM framework
(via "struct pwm_chip chip" member of struct mtk_pwm_chip).

For instance, if you will add more info to this data structure you could do it this way:

struct mtk_pwm_platform_data_other {
	typex memberx;
	typey membery;
	// ...
};

struct mtk_pwm_platform_data {
	unsigned int num_pwms;
	struct mtk_pwm_platform_data_other other_data;
};

And have struct mtk_pwm_chip as follows:
struct mtk_pwm_chip {
	struct pwm_chip chip;
	void __iomem *regs;
	struct clk *clks[MTK_CLK_MAX];
	struct mtk_pwm_platform_data_other *other_data;
}

and in probe:

static int mtk_pwm_probe(struct platform_device *pdev)
{
	struct mtk_pwm_platform_data *data;
	// ...
	data = of_device_get_match_data(&pdev->dev);
	if (data == NULL)
		return -EINVAL;
	pc->other_data = data->other_data;
	// ...
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
					 * data structure and you could use it from here. */

	// ...
}

At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
to be part of struct mtk_pwm_chip.

Thanks,
Claudiu

> so, we want to keep it and make the interface more flexible. 
> 
>>> +};
>>> +
>>> +static const unsigned int mtk_pwm_reg_offset[] = {
>>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>>>  };
>>>  
>>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
>>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>>>  				unsigned int offset)
>>>  {
>>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>>>  				  unsigned int num, unsigned int offset,
>>>  				  u32 value)
>>>  {
>>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	if (!pc)
>>>  		return -ENOMEM;
>>>  
>>> +	pc->data = of_device_get_match_data(&pdev->dev);
>> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
>> and you may use here a stack allocated variable to store the number of PWMs returned
>> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
>> any, you could get that information from chip.npwm.
>> You could also check here the number of PWMs returned via of_device_get_match_data()
>> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
>> pwmchip_add() will fail).
>>
> Here, I will add the NULL pointer checking for "pc->data", and it will
> be released, soon.
> 
>>> +
>>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>>>  	if (IS_ERR(pc->regs))
>>>  		return PTR_ERR(pc->regs);
>>>  
>>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
>>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
>>> -		if (IS_ERR(pc->clks[i]))
>>> +		if (IS_ERR(pc->clks[i])) {
>>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
>>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>>>  			return PTR_ERR(pc->clks[i]);
>>> +		}
>>>  	}
>>>  
>>>  	platform_set_drvdata(pdev, pc);
>>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	pc->chip.dev = &pdev->dev;
>>>  	pc->chip.ops = &mtk_pwm_ops;
>>>  	pc->chip.base = -1;
>>> -	pc->chip.npwm = 5;
>>> +	pc->chip.npwm = pc->data->num_pwms;
>>>  
>>>  	ret = pwmchip_add(&pc->chip);
>>>  	if (ret < 0) {
>>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>>>  	return pwmchip_remove(&pc->chip);
>>>  }
>>>  
>>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
>>> +	.num_pwms = 8,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
>>> +	.num_pwms = 6,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
>>> +	.num_pwms = 5,
>>> +};
>>> +
>>>  static const struct of_device_id mtk_pwm_of_match[] = {
>>> -	{ .compatible = "mediatek,mt7623-pwm" },
>>> -	{ }
>>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
>>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
>>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
>>> +	{ },
>>>  };
>>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>>>  
>>>
> 
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-24 13:25         ` m18063
  0 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-24 13:25 UTC (permalink / raw)
  To: Zhi Mao
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen

Hi Zhi,

Please see my answer below.

On 23.10.2017 14:13, Zhi Mao wrote:
> Hi Claudiu
> 
> please check the comments as below.
> 
> Regards
> Zhi
> 
> On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
>> Hi Zhi,
>>
>> I have few comments regarding your patch. Please see them below.
>>
>> Thanks,
>> Claudiu
>>
>> On 22.08.2017 05:09, Zhi Mao wrote:
>>> Add support to MT2712 and MT7622.
>>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
>>> add mtk_pwm_reg_offset array for pwm register offset.
>>>
>>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
>>> ---
>>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>>>  1 file changed, 42 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
>>> index 1d78ab1..ccd86e7 100644
>>> --- a/drivers/pwm/pwm-mediatek.c
>>> +++ b/drivers/pwm/pwm-mediatek.c
>>> @@ -16,6 +16,7 @@
>>>  #include <linux/module.h>
>>>  #include <linux/clk.h>
>>>  #include <linux/of.h>
>>> +#include <linux/of_device.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/pwm.h>
>>>  #include <linux/slab.h>
>>> @@ -40,11 +41,19 @@ enum {
>>>  	MTK_CLK_PWM3,
>>>  	MTK_CLK_PWM4,
>>>  	MTK_CLK_PWM5,
>>> +	MTK_CLK_PWM6,
>>> +	MTK_CLK_PWM7,
>>> +	MTK_CLK_PWM8,
>>>  	MTK_CLK_MAX,
>>>  };
>>>  
>>> -static const char * const mtk_pwm_clk_name[] = {
>>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
>>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
>>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
>>> +	"pwm8"
>>> +};
>>> +
>>> +struct mtk_pwm_platform_data {
>>> +	unsigned int num_pwms;
>>>  };
>>>  
>>>  /**
>>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>>>  	struct pwm_chip chip;
>>>  	void __iomem *regs;
>>>  	struct clk *clks[MTK_CLK_MAX];
>>> +	const struct mtk_pwm_platform_data *data;
>> I think you can remove this member since you only use it to initialize chip.npwm,
>> in probe function, just before platform_set_drvdata().
>>
>> 	pc->chip.npwm = pc->data->pwm_nums;
>>
>> 	platform_set_drvdata(pdev, pc);
> Here, the member of "mtk_pwm_platform_data" is an extension interface of
> pwm information for MTK SOC chips. At present, we use it to initialize
> npwms,

and maybe we will have more informations to use, in later. 

The use of *maybe* in here suggest me that this will not necessary happen.
Actually, what I wanted to emphasize is that, for the moment, you are keeping
same information in both driver private data structure and PWM framework data
structure. So, even if in future you will add more members to this data structure,
you will have the number of PWMs stored in both, your driver data structure
(via "struct mtk_pwm_platform_data *data" member) and PWM framework
(via "struct pwm_chip chip" member of struct mtk_pwm_chip).

For instance, if you will add more info to this data structure you could do it this way:

struct mtk_pwm_platform_data_other {
	typex memberx;
	typey membery;
	// ...
};

struct mtk_pwm_platform_data {
	unsigned int num_pwms;
	struct mtk_pwm_platform_data_other other_data;
};

And have struct mtk_pwm_chip as follows:
struct mtk_pwm_chip {
	struct pwm_chip chip;
	void __iomem *regs;
	struct clk *clks[MTK_CLK_MAX];
	struct mtk_pwm_platform_data_other *other_data;
}

and in probe:

static int mtk_pwm_probe(struct platform_device *pdev)
{
	struct mtk_pwm_platform_data *data;
	// ...
	data = of_device_get_match_data(&pdev->dev);
	if (data == NULL)
		return -EINVAL;
	pc->other_data = data->other_data;
	// ...
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
					 * data structure and you could use it from here. */

	// ...
}

At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
to be part of struct mtk_pwm_chip.

Thanks,
Claudiu

> so, we want to keep it and make the interface more flexible. 
> 
>>> +};
>>> +
>>> +static const unsigned int mtk_pwm_reg_offset[] = {
>>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>>>  };
>>>  
>>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
>>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>>>  				unsigned int offset)
>>>  {
>>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>>>  				  unsigned int num, unsigned int offset,
>>>  				  u32 value)
>>>  {
>>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	if (!pc)
>>>  		return -ENOMEM;
>>>  
>>> +	pc->data = of_device_get_match_data(&pdev->dev);
>> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
>> and you may use here a stack allocated variable to store the number of PWMs returned
>> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
>> any, you could get that information from chip.npwm.
>> You could also check here the number of PWMs returned via of_device_get_match_data()
>> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
>> pwmchip_add() will fail).
>>
> Here, I will add the NULL pointer checking for "pc->data", and it will
> be released, soon.
> 
>>> +
>>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>>>  	if (IS_ERR(pc->regs))
>>>  		return PTR_ERR(pc->regs);
>>>  
>>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
>>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
>>> -		if (IS_ERR(pc->clks[i]))
>>> +		if (IS_ERR(pc->clks[i])) {
>>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
>>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>>>  			return PTR_ERR(pc->clks[i]);
>>> +		}
>>>  	}
>>>  
>>>  	platform_set_drvdata(pdev, pc);
>>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	pc->chip.dev = &pdev->dev;
>>>  	pc->chip.ops = &mtk_pwm_ops;
>>>  	pc->chip.base = -1;
>>> -	pc->chip.npwm = 5;
>>> +	pc->chip.npwm = pc->data->num_pwms;
>>>  
>>>  	ret = pwmchip_add(&pc->chip);
>>>  	if (ret < 0) {
>>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>>>  	return pwmchip_remove(&pc->chip);
>>>  }
>>>  
>>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
>>> +	.num_pwms = 8,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
>>> +	.num_pwms = 6,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
>>> +	.num_pwms = 5,
>>> +};
>>> +
>>>  static const struct of_device_id mtk_pwm_of_match[] = {
>>> -	{ .compatible = "mediatek,mt7623-pwm" },
>>> -	{ }
>>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
>>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
>>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
>>> +	{ },
>>>  };
>>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>>>  
>>>
> 
> 

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-24 13:25         ` m18063
  0 siblings, 0 replies; 24+ messages in thread
From: m18063 @ 2017-10-24 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Zhi,

Please see my answer below.

On 23.10.2017 14:13, Zhi Mao wrote:
> Hi Claudiu
> 
> please check the comments as below.
> 
> Regards
> Zhi
> 
> On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
>> Hi Zhi,
>>
>> I have few comments regarding your patch. Please see them below.
>>
>> Thanks,
>> Claudiu
>>
>> On 22.08.2017 05:09, Zhi Mao wrote:
>>> Add support to MT2712 and MT7622.
>>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
>>> add mtk_pwm_reg_offset array for pwm register offset.
>>>
>>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
>>> ---
>>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
>>>  1 file changed, 42 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
>>> index 1d78ab1..ccd86e7 100644
>>> --- a/drivers/pwm/pwm-mediatek.c
>>> +++ b/drivers/pwm/pwm-mediatek.c
>>> @@ -16,6 +16,7 @@
>>>  #include <linux/module.h>
>>>  #include <linux/clk.h>
>>>  #include <linux/of.h>
>>> +#include <linux/of_device.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/pwm.h>
>>>  #include <linux/slab.h>
>>> @@ -40,11 +41,19 @@ enum {
>>>  	MTK_CLK_PWM3,
>>>  	MTK_CLK_PWM4,
>>>  	MTK_CLK_PWM5,
>>> +	MTK_CLK_PWM6,
>>> +	MTK_CLK_PWM7,
>>> +	MTK_CLK_PWM8,
>>>  	MTK_CLK_MAX,
>>>  };
>>>  
>>> -static const char * const mtk_pwm_clk_name[] = {
>>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
>>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
>>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
>>> +	"pwm8"
>>> +};
>>> +
>>> +struct mtk_pwm_platform_data {
>>> +	unsigned int num_pwms;
>>>  };
>>>  
>>>  /**
>>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
>>>  	struct pwm_chip chip;
>>>  	void __iomem *regs;
>>>  	struct clk *clks[MTK_CLK_MAX];
>>> +	const struct mtk_pwm_platform_data *data;
>> I think you can remove this member since you only use it to initialize chip.npwm,
>> in probe function, just before platform_set_drvdata().
>>
>> 	pc->chip.npwm = pc->data->pwm_nums;
>>
>> 	platform_set_drvdata(pdev, pc);
> Here, the member of "mtk_pwm_platform_data" is an extension interface of
> pwm information for MTK SOC chips. At present, we use it to initialize
> npwms,

and maybe we will have more informations to use, in later. 

The use of *maybe* in here suggest me that this will not necessary happen.
Actually, what I wanted to emphasize is that, for the moment, you are keeping
same information in both driver private data structure and PWM framework data
structure. So, even if in future you will add more members to this data structure,
you will have the number of PWMs stored in both, your driver data structure
(via "struct mtk_pwm_platform_data *data" member) and PWM framework
(via "struct pwm_chip chip" member of struct mtk_pwm_chip).

For instance, if you will add more info to this data structure you could do it this way:

struct mtk_pwm_platform_data_other {
	typex memberx;
	typey membery;
	// ...
};

struct mtk_pwm_platform_data {
	unsigned int num_pwms;
	struct mtk_pwm_platform_data_other other_data;
};

And have struct mtk_pwm_chip as follows:
struct mtk_pwm_chip {
	struct pwm_chip chip;
	void __iomem *regs;
	struct clk *clks[MTK_CLK_MAX];
	struct mtk_pwm_platform_data_other *other_data;
}

and in probe:

static int mtk_pwm_probe(struct platform_device *pdev)
{
	struct mtk_pwm_platform_data *data;
	// ...
	data = of_device_get_match_data(&pdev->dev);
	if (data == NULL)
		return -EINVAL;
	pc->other_data = data->other_data;
	// ...
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &mtk_pwm_ops;
 	pc->chip.base = -1;
	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
					 * data structure and you could use it from here. */

	// ...
}

At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
to be part of struct mtk_pwm_chip.

Thanks,
Claudiu

> so, we want to keep it and make the interface more flexible. 
> 
>>> +};
>>> +
>>> +static const unsigned int mtk_pwm_reg_offset[] = {
>>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
>>>  };
>>>  
>>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
>>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
>>>  				unsigned int offset)
>>>  {
>>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
>>>  				  unsigned int num, unsigned int offset,
>>>  				  u32 value)
>>>  {
>>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
>>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
>>>  }
>>>  
>>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	if (!pc)
>>>  		return -ENOMEM;
>>>  
>>> +	pc->data = of_device_get_match_data(&pdev->dev);
>> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
>> and you may use here a stack allocated variable to store the number of PWMs returned
>> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
>> any, you could get that information from chip.npwm.
>> You could also check here the number of PWMs returned via of_device_get_match_data()
>> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
>> pwmchip_add() will fail).
>>
> Here, I will add the NULL pointer checking for "pc->data", and it will
> be released, soon.
> 
>>> +
>>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
>>>  	if (IS_ERR(pc->regs))
>>>  		return PTR_ERR(pc->regs);
>>>  
>>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
>>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
>>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
>>> -		if (IS_ERR(pc->clks[i]))
>>> +		if (IS_ERR(pc->clks[i])) {
>>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
>>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
>>>  			return PTR_ERR(pc->clks[i]);
>>> +		}
>>>  	}
>>>  
>>>  	platform_set_drvdata(pdev, pc);
>>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
>>>  	pc->chip.dev = &pdev->dev;
>>>  	pc->chip.ops = &mtk_pwm_ops;
>>>  	pc->chip.base = -1;
>>> -	pc->chip.npwm = 5;
>>> +	pc->chip.npwm = pc->data->num_pwms;
>>>  
>>>  	ret = pwmchip_add(&pc->chip);
>>>  	if (ret < 0) {
>>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
>>>  	return pwmchip_remove(&pc->chip);
>>>  }
>>>  
>>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
>>> +	.num_pwms = 8,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
>>> +	.num_pwms = 6,
>>> +};
>>> +
>>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
>>> +	.num_pwms = 5,
>>> +};
>>> +
>>>  static const struct of_device_id mtk_pwm_of_match[] = {
>>> -	{ .compatible = "mediatek,mt7623-pwm" },
>>> -	{ }
>>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
>>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
>>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
>>> +	{ },
>>>  };
>>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
>>>  
>>>
> 
> 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
  2017-10-24 13:25         ` m18063
  (?)
@ 2017-10-25  7:06           ` Zhi Mao
  -1 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-25  7:06 UTC (permalink / raw)
  To: m18063
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen, linux-arm-kernel

Hi Claudiu,

Thanks for your comments.
I updated this file, according to your suggestions.
Please have a review.

Regards
Zhi

On Tue, 2017-10-24 at 16:25 +0300, m18063 wrote:
> Hi Zhi,
> 
> Please see my answer below.
> 
> On 23.10.2017 14:13, Zhi Mao wrote:
> > Hi Claudiu
> > 
> > please check the comments as below.
> > 
> > Regards
> > Zhi
> > 
> > On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> >> Hi Zhi,
> >>
> >> I have few comments regarding your patch. Please see them below.
> >>
> >> Thanks,
> >> Claudiu
> >>
> >> On 22.08.2017 05:09, Zhi Mao wrote:
> >>> Add support to MT2712 and MT7622.
> >>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> >>> add mtk_pwm_reg_offset array for pwm register offset.
> >>>
> >>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> >>> ---
> >>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >>>  1 file changed, 42 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> >>> index 1d78ab1..ccd86e7 100644
> >>> --- a/drivers/pwm/pwm-mediatek.c
> >>> +++ b/drivers/pwm/pwm-mediatek.c
> >>> @@ -16,6 +16,7 @@
> >>>  #include <linux/module.h>
> >>>  #include <linux/clk.h>
> >>>  #include <linux/of.h>
> >>> +#include <linux/of_device.h>
> >>>  #include <linux/platform_device.h>
> >>>  #include <linux/pwm.h>
> >>>  #include <linux/slab.h>
> >>> @@ -40,11 +41,19 @@ enum {
> >>>  	MTK_CLK_PWM3,
> >>>  	MTK_CLK_PWM4,
> >>>  	MTK_CLK_PWM5,
> >>> +	MTK_CLK_PWM6,
> >>> +	MTK_CLK_PWM7,
> >>> +	MTK_CLK_PWM8,
> >>>  	MTK_CLK_MAX,
> >>>  };
> >>>  
> >>> -static const char * const mtk_pwm_clk_name[] = {
> >>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> >>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> >>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> >>> +	"pwm8"
> >>> +};
> >>> +
> >>> +struct mtk_pwm_platform_data {
> >>> +	unsigned int num_pwms;
> >>>  };
> >>>  
> >>>  /**
> >>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >>>  	struct pwm_chip chip;
> >>>  	void __iomem *regs;
> >>>  	struct clk *clks[MTK_CLK_MAX];
> >>> +	const struct mtk_pwm_platform_data *data;
> >> I think you can remove this member since you only use it to initialize chip.npwm,
> >> in probe function, just before platform_set_drvdata().
> >>
> >> 	pc->chip.npwm = pc->data->pwm_nums;
> >>
> >> 	platform_set_drvdata(pdev, pc);
> > Here, the member of "mtk_pwm_platform_data" is an extension interface of
> > pwm information for MTK SOC chips. At present, we use it to initialize
> > npwms,
> 
> and maybe we will have more informations to use, in later. 
> 
> The use of *maybe* in here suggest me that this will not necessary happen.
> Actually, what I wanted to emphasize is that, for the moment, you are keeping
> same information in both driver private data structure and PWM framework data
> structure. So, even if in future you will add more members to this data structure,
> you will have the number of PWMs stored in both, your driver data structure
> (via "struct mtk_pwm_platform_data *data" member) and PWM framework
> (via "struct pwm_chip chip" member of struct mtk_pwm_chip).
> 
> For instance, if you will add more info to this data structure you could do it this way:
> 
> struct mtk_pwm_platform_data_other {
> 	typex memberx;
> 	typey membery;
> 	// ...
> };
> 
> struct mtk_pwm_platform_data {
> 	unsigned int num_pwms;
> 	struct mtk_pwm_platform_data_other other_data;
> };
> 
> And have struct mtk_pwm_chip as follows:
> struct mtk_pwm_chip {
> 	struct pwm_chip chip;
> 	void __iomem *regs;
> 	struct clk *clks[MTK_CLK_MAX];
> 	struct mtk_pwm_platform_data_other *other_data;
> }
> 
> and in probe:
> 
> static int mtk_pwm_probe(struct platform_device *pdev)
> {
> 	struct mtk_pwm_platform_data *data;
> 	// ...
> 	data = of_device_get_match_data(&pdev->dev);
> 	if (data == NULL)
> 		return -EINVAL;
> 	pc->other_data = data->other_data;
> 	// ...
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> 	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
> 					 * data structure and you could use it from here. */
> 
> 	// ...
> }
> 
> At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
> to be part of struct mtk_pwm_chip.
> 
> Thanks,
> Claudiu
> 
> > so, we want to keep it and make the interface more flexible. 
> > 
> >>> +};
> >>> +
> >>> +static const unsigned int mtk_pwm_reg_offset[] = {
> >>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >>>  };
> >>>  
> >>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> >>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >>>  				unsigned int offset)
> >>>  {
> >>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >>>  				  unsigned int num, unsigned int offset,
> >>>  				  u32 value)
> >>>  {
> >>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> >>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	if (!pc)
> >>>  		return -ENOMEM;
> >>>  
> >>> +	pc->data = of_device_get_match_data(&pdev->dev);
> >> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> >> and you may use here a stack allocated variable to store the number of PWMs returned
> >> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> >> any, you could get that information from chip.npwm.
> >> You could also check here the number of PWMs returned via of_device_get_match_data()
> >> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> >> pwmchip_add() will fail).
> >>
> > Here, I will add the NULL pointer checking for "pc->data", and it will
> > be released, soon.
> > 
> >>> +
> >>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >>>  	if (IS_ERR(pc->regs))
> >>>  		return PTR_ERR(pc->regs);
> >>>  
> >>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> >>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> >>> -		if (IS_ERR(pc->clks[i]))
> >>> +		if (IS_ERR(pc->clks[i])) {
> >>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> >>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >>>  			return PTR_ERR(pc->clks[i]);
> >>> +		}
> >>>  	}
> >>>  
> >>>  	platform_set_drvdata(pdev, pc);
> >>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	pc->chip.dev = &pdev->dev;
> >>>  	pc->chip.ops = &mtk_pwm_ops;
> >>>  	pc->chip.base = -1;
> >>> -	pc->chip.npwm = 5;
> >>> +	pc->chip.npwm = pc->data->num_pwms;
> >>>  
> >>>  	ret = pwmchip_add(&pc->chip);
> >>>  	if (ret < 0) {
> >>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >>>  	return pwmchip_remove(&pc->chip);
> >>>  }
> >>>  
> >>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> >>> +	.num_pwms = 8,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> >>> +	.num_pwms = 6,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> >>> +	.num_pwms = 5,
> >>> +};
> >>> +
> >>>  static const struct of_device_id mtk_pwm_of_match[] = {
> >>> -	{ .compatible = "mediatek,mt7623-pwm" },
> >>> -	{ }
> >>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> >>> +	{ },
> >>>  };
> >>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >>>  
> >>>
> > 
> > 

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

* Re: [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-25  7:06           ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-25  7:06 UTC (permalink / raw)
  To: m18063
  Cc: john, Thierry Reding, Rob Herring, Mark Rutland,
	Matthias Brugger, linux-pwm, zhenbao.liu, devicetree,
	srv_heupstream, sean.wang, linux-kernel, linux-mediatek, yt.shen,
	yingjoe.chen

Hi Claudiu,

Thanks for your comments.
I updated this file, according to your suggestions.
Please have a review.

Regards
Zhi

On Tue, 2017-10-24 at 16:25 +0300, m18063 wrote:
> Hi Zhi,
> 
> Please see my answer below.
> 
> On 23.10.2017 14:13, Zhi Mao wrote:
> > Hi Claudiu
> > 
> > please check the comments as below.
> > 
> > Regards
> > Zhi
> > 
> > On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> >> Hi Zhi,
> >>
> >> I have few comments regarding your patch. Please see them below.
> >>
> >> Thanks,
> >> Claudiu
> >>
> >> On 22.08.2017 05:09, Zhi Mao wrote:
> >>> Add support to MT2712 and MT7622.
> >>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> >>> add mtk_pwm_reg_offset array for pwm register offset.
> >>>
> >>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> >>> ---
> >>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >>>  1 file changed, 42 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> >>> index 1d78ab1..ccd86e7 100644
> >>> --- a/drivers/pwm/pwm-mediatek.c
> >>> +++ b/drivers/pwm/pwm-mediatek.c
> >>> @@ -16,6 +16,7 @@
> >>>  #include <linux/module.h>
> >>>  #include <linux/clk.h>
> >>>  #include <linux/of.h>
> >>> +#include <linux/of_device.h>
> >>>  #include <linux/platform_device.h>
> >>>  #include <linux/pwm.h>
> >>>  #include <linux/slab.h>
> >>> @@ -40,11 +41,19 @@ enum {
> >>>  	MTK_CLK_PWM3,
> >>>  	MTK_CLK_PWM4,
> >>>  	MTK_CLK_PWM5,
> >>> +	MTK_CLK_PWM6,
> >>> +	MTK_CLK_PWM7,
> >>> +	MTK_CLK_PWM8,
> >>>  	MTK_CLK_MAX,
> >>>  };
> >>>  
> >>> -static const char * const mtk_pwm_clk_name[] = {
> >>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> >>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> >>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> >>> +	"pwm8"
> >>> +};
> >>> +
> >>> +struct mtk_pwm_platform_data {
> >>> +	unsigned int num_pwms;
> >>>  };
> >>>  
> >>>  /**
> >>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >>>  	struct pwm_chip chip;
> >>>  	void __iomem *regs;
> >>>  	struct clk *clks[MTK_CLK_MAX];
> >>> +	const struct mtk_pwm_platform_data *data;
> >> I think you can remove this member since you only use it to initialize chip.npwm,
> >> in probe function, just before platform_set_drvdata().
> >>
> >> 	pc->chip.npwm = pc->data->pwm_nums;
> >>
> >> 	platform_set_drvdata(pdev, pc);
> > Here, the member of "mtk_pwm_platform_data" is an extension interface of
> > pwm information for MTK SOC chips. At present, we use it to initialize
> > npwms,
> 
> and maybe we will have more informations to use, in later. 
> 
> The use of *maybe* in here suggest me that this will not necessary happen.
> Actually, what I wanted to emphasize is that, for the moment, you are keeping
> same information in both driver private data structure and PWM framework data
> structure. So, even if in future you will add more members to this data structure,
> you will have the number of PWMs stored in both, your driver data structure
> (via "struct mtk_pwm_platform_data *data" member) and PWM framework
> (via "struct pwm_chip chip" member of struct mtk_pwm_chip).
> 
> For instance, if you will add more info to this data structure you could do it this way:
> 
> struct mtk_pwm_platform_data_other {
> 	typex memberx;
> 	typey membery;
> 	// ...
> };
> 
> struct mtk_pwm_platform_data {
> 	unsigned int num_pwms;
> 	struct mtk_pwm_platform_data_other other_data;
> };
> 
> And have struct mtk_pwm_chip as follows:
> struct mtk_pwm_chip {
> 	struct pwm_chip chip;
> 	void __iomem *regs;
> 	struct clk *clks[MTK_CLK_MAX];
> 	struct mtk_pwm_platform_data_other *other_data;
> }
> 
> and in probe:
> 
> static int mtk_pwm_probe(struct platform_device *pdev)
> {
> 	struct mtk_pwm_platform_data *data;
> 	// ...
> 	data = of_device_get_match_data(&pdev->dev);
> 	if (data == NULL)
> 		return -EINVAL;
> 	pc->other_data = data->other_data;
> 	// ...
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> 	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
> 					 * data structure and you could use it from here. */
> 
> 	// ...
> }
> 
> At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
> to be part of struct mtk_pwm_chip.
> 
> Thanks,
> Claudiu
> 
> > so, we want to keep it and make the interface more flexible. 
> > 
> >>> +};
> >>> +
> >>> +static const unsigned int mtk_pwm_reg_offset[] = {
> >>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >>>  };
> >>>  
> >>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> >>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >>>  				unsigned int offset)
> >>>  {
> >>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >>>  				  unsigned int num, unsigned int offset,
> >>>  				  u32 value)
> >>>  {
> >>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> >>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	if (!pc)
> >>>  		return -ENOMEM;
> >>>  
> >>> +	pc->data = of_device_get_match_data(&pdev->dev);
> >> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> >> and you may use here a stack allocated variable to store the number of PWMs returned
> >> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> >> any, you could get that information from chip.npwm.
> >> You could also check here the number of PWMs returned via of_device_get_match_data()
> >> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> >> pwmchip_add() will fail).
> >>
> > Here, I will add the NULL pointer checking for "pc->data", and it will
> > be released, soon.
> > 
> >>> +
> >>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >>>  	if (IS_ERR(pc->regs))
> >>>  		return PTR_ERR(pc->regs);
> >>>  
> >>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> >>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> >>> -		if (IS_ERR(pc->clks[i]))
> >>> +		if (IS_ERR(pc->clks[i])) {
> >>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> >>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >>>  			return PTR_ERR(pc->clks[i]);
> >>> +		}
> >>>  	}
> >>>  
> >>>  	platform_set_drvdata(pdev, pc);
> >>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	pc->chip.dev = &pdev->dev;
> >>>  	pc->chip.ops = &mtk_pwm_ops;
> >>>  	pc->chip.base = -1;
> >>> -	pc->chip.npwm = 5;
> >>> +	pc->chip.npwm = pc->data->num_pwms;
> >>>  
> >>>  	ret = pwmchip_add(&pc->chip);
> >>>  	if (ret < 0) {
> >>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >>>  	return pwmchip_remove(&pc->chip);
> >>>  }
> >>>  
> >>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> >>> +	.num_pwms = 8,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> >>> +	.num_pwms = 6,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> >>> +	.num_pwms = 5,
> >>> +};
> >>> +
> >>>  static const struct of_device_id mtk_pwm_of_match[] = {
> >>> -	{ .compatible = "mediatek,mt7623-pwm" },
> >>> -	{ }
> >>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> >>> +	{ },
> >>>  };
> >>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >>>  
> >>>
> > 
> > 

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

* [PATCH v4 1/1] pwm: mediatek: add MT2712/MT7622 support
@ 2017-10-25  7:06           ` Zhi Mao
  0 siblings, 0 replies; 24+ messages in thread
From: Zhi Mao @ 2017-10-25  7:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Claudiu,

Thanks for your comments.
I updated this file, according to your suggestions.
Please have a review.

Regards
Zhi

On Tue, 2017-10-24 at 16:25 +0300, m18063 wrote:
> Hi Zhi,
> 
> Please see my answer below.
> 
> On 23.10.2017 14:13, Zhi Mao wrote:
> > Hi Claudiu
> > 
> > please check the comments as below.
> > 
> > Regards
> > Zhi
> > 
> > On Mon, 2017-10-23 at 11:22 +0300, m18063 wrote:
> >> Hi Zhi,
> >>
> >> I have few comments regarding your patch. Please see them below.
> >>
> >> Thanks,
> >> Claudiu
> >>
> >> On 22.08.2017 05:09, Zhi Mao wrote:
> >>> Add support to MT2712 and MT7622.
> >>> Due to register offset address of pwm7 for MT2712 is not fixed 0x40,
> >>> add mtk_pwm_reg_offset array for pwm register offset.
> >>>
> >>> Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> >>> ---
> >>>  drivers/pwm/pwm-mediatek.c |   51 ++++++++++++++++++++++++++++++++++++--------
> >>>  1 file changed, 42 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
> >>> index 1d78ab1..ccd86e7 100644
> >>> --- a/drivers/pwm/pwm-mediatek.c
> >>> +++ b/drivers/pwm/pwm-mediatek.c
> >>> @@ -16,6 +16,7 @@
> >>>  #include <linux/module.h>
> >>>  #include <linux/clk.h>
> >>>  #include <linux/of.h>
> >>> +#include <linux/of_device.h>
> >>>  #include <linux/platform_device.h>
> >>>  #include <linux/pwm.h>
> >>>  #include <linux/slab.h>
> >>> @@ -40,11 +41,19 @@ enum {
> >>>  	MTK_CLK_PWM3,
> >>>  	MTK_CLK_PWM4,
> >>>  	MTK_CLK_PWM5,
> >>> +	MTK_CLK_PWM6,
> >>> +	MTK_CLK_PWM7,
> >>> +	MTK_CLK_PWM8,
> >>>  	MTK_CLK_MAX,
> >>>  };
> >>>  
> >>> -static const char * const mtk_pwm_clk_name[] = {
> >>> -	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"
> >>> +static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
> >>> +	"main", "top", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7",
> >>> +	"pwm8"
> >>> +};
> >>> +
> >>> +struct mtk_pwm_platform_data {
> >>> +	unsigned int num_pwms;
> >>>  };
> >>>  
> >>>  /**
> >>> @@ -57,6 +66,11 @@ struct mtk_pwm_chip {
> >>>  	struct pwm_chip chip;
> >>>  	void __iomem *regs;
> >>>  	struct clk *clks[MTK_CLK_MAX];
> >>> +	const struct mtk_pwm_platform_data *data;
> >> I think you can remove this member since you only use it to initialize chip.npwm,
> >> in probe function, just before platform_set_drvdata().
> >>
> >> 	pc->chip.npwm = pc->data->pwm_nums;
> >>
> >> 	platform_set_drvdata(pdev, pc);
> > Here, the member of "mtk_pwm_platform_data" is an extension interface of
> > pwm information for MTK SOC chips. At present, we use it to initialize
> > npwms,
> 
> and maybe we will have more informations to use, in later. 
> 
> The use of *maybe* in here suggest me that this will not necessary happen.
> Actually, what I wanted to emphasize is that, for the moment, you are keeping
> same information in both driver private data structure and PWM framework data
> structure. So, even if in future you will add more members to this data structure,
> you will have the number of PWMs stored in both, your driver data structure
> (via "struct mtk_pwm_platform_data *data" member) and PWM framework
> (via "struct pwm_chip chip" member of struct mtk_pwm_chip).
> 
> For instance, if you will add more info to this data structure you could do it this way:
> 
> struct mtk_pwm_platform_data_other {
> 	typex memberx;
> 	typey membery;
> 	// ...
> };
> 
> struct mtk_pwm_platform_data {
> 	unsigned int num_pwms;
> 	struct mtk_pwm_platform_data_other other_data;
> };
> 
> And have struct mtk_pwm_chip as follows:
> struct mtk_pwm_chip {
> 	struct pwm_chip chip;
> 	void __iomem *regs;
> 	struct clk *clks[MTK_CLK_MAX];
> 	struct mtk_pwm_platform_data_other *other_data;
> }
> 
> and in probe:
> 
> static int mtk_pwm_probe(struct platform_device *pdev)
> {
> 	struct mtk_pwm_platform_data *data;
> 	// ...
> 	data = of_device_get_match_data(&pdev->dev);
> 	if (data == NULL)
> 		return -EINVAL;
> 	pc->other_data = data->other_data;
> 	// ...
>  	pc->chip.dev = &pdev->dev;
>  	pc->chip.ops = &mtk_pwm_ops;
>  	pc->chip.base = -1;
> 	pc->chip.npwm = data->num_pwms; /* Here you store the num_pwms in PWM framework
> 					 * data structure and you could use it from here. */
> 
> 	// ...
> }
> 
> At this moment I think there is no need for "const struct mtk_pwm_platform_data" member
> to be part of struct mtk_pwm_chip.
> 
> Thanks,
> Claudiu
> 
> > so, we want to keep it and make the interface more flexible. 
> > 
> >>> +};
> >>> +
> >>> +static const unsigned int mtk_pwm_reg_offset[] = {
> >>> +	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
> >>>  };
> >>>  
> >>>  static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
> >>> @@ -103,14 +117,14 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >>>  static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
> >>>  				unsigned int offset)
> >>>  {
> >>> -	return readl(chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	return readl(chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
> >>>  				  unsigned int num, unsigned int offset,
> >>>  				  u32 value)
> >>>  {
> >>> -	writel(value, chip->regs + 0x10 + (num * 0x40) + offset);
> >>> +	writel(value, chip->regs + mtk_pwm_reg_offset[num] + offset);
> >>>  }
> >>>  
> >>>  static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> >>> @@ -194,15 +208,20 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	if (!pc)
> >>>  		return -ENOMEM;
> >>>  
> >>> +	pc->data = of_device_get_match_data(&pdev->dev);
> >> You forgot to check pc->data == NULL (in case device tree inputs are not provided)
> >> and you may use here a stack allocated variable to store the number of PWMs returned
> >> by of_device_get_match_data(). This is used only for pc->chip.npwm, and anyway, if
> >> any, you could get that information from chip.npwm.
> >> You could also check here the number of PWMs returned via of_device_get_match_data()
> >> to avoid waiting for pwmchip_add() to fail (e.g. if number of PWMs is zero, the
> >> pwmchip_add() will fail).
> >>
> > Here, I will add the NULL pointer checking for "pc->data", and it will
> > be released, soon.
> > 
> >>> +
> >>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >>>  	pc->regs = devm_ioremap_resource(&pdev->dev, res);
> >>>  	if (IS_ERR(pc->regs))
> >>>  		return PTR_ERR(pc->regs);
> >>>  
> >>> -	for (i = 0; i < MTK_CLK_MAX; i++) {
> >>> +	for (i = 0; i < pc->data->num_pwms + 2; i++) {
> >>>  		pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
> >>> -		if (IS_ERR(pc->clks[i]))
> >>> +		if (IS_ERR(pc->clks[i])) {
> >>> +			dev_err(&pdev->dev, "clock: %s fail: %ld\n",
> >>> +				mtk_pwm_clk_name[i], PTR_ERR(pc->clks[i]));
> >>>  			return PTR_ERR(pc->clks[i]);
> >>> +		}
> >>>  	}
> >>>  
> >>>  	platform_set_drvdata(pdev, pc);
> >>> @@ -210,7 +229,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
> >>>  	pc->chip.dev = &pdev->dev;
> >>>  	pc->chip.ops = &mtk_pwm_ops;
> >>>  	pc->chip.base = -1;
> >>> -	pc->chip.npwm = 5;
> >>> +	pc->chip.npwm = pc->data->num_pwms;
> >>>  
> >>>  	ret = pwmchip_add(&pc->chip);
> >>>  	if (ret < 0) {
> >>> @@ -228,9 +247,23 @@ static int mtk_pwm_remove(struct platform_device *pdev)
> >>>  	return pwmchip_remove(&pc->chip);
> >>>  }
> >>>  
> >>> +static const struct mtk_pwm_platform_data mt2712_pwm_data = {
> >>> +	.num_pwms = 8,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7622_pwm_data = {
> >>> +	.num_pwms = 6,
> >>> +};
> >>> +
> >>> +static const struct mtk_pwm_platform_data mt7623_pwm_data = {
> >>> +	.num_pwms = 5,
> >>> +};
> >>> +
> >>>  static const struct of_device_id mtk_pwm_of_match[] = {
> >>> -	{ .compatible = "mediatek,mt7623-pwm" },
> >>> -	{ }
> >>> +	{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
> >>> +	{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
> >>> +	{ },
> >>>  };
> >>>  MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
> >>>  
> >>>
> > 
> > 

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

end of thread, other threads:[~2017-10-25  7:06 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-22  2:09 [PATCH v4 0/1] pwm: mediatek: add MT2712/MT7622 support Zhi Mao
2017-08-22  2:09 ` Zhi Mao
2017-08-22  2:09 ` Zhi Mao
2017-08-22  2:09 ` [PATCH v4 1/1] " Zhi Mao
2017-08-22  2:09   ` Zhi Mao
2017-08-22  2:09   ` Zhi Mao
2017-09-20  8:48   ` Zhi Mao
2017-09-20  8:48     ` Zhi Mao
2017-09-20  8:48     ` Zhi Mao
2017-10-23  5:27     ` Zhi Mao
2017-10-23  5:27       ` Zhi Mao
2017-10-23  5:27       ` Zhi Mao
2017-10-23  8:22   ` m18063
2017-10-23  8:22     ` m18063
2017-10-23  8:22     ` m18063
2017-10-23 11:13     ` Zhi Mao
2017-10-23 11:13       ` Zhi Mao
2017-10-23 11:13       ` Zhi Mao
2017-10-24 13:25       ` m18063
2017-10-24 13:25         ` m18063
2017-10-24 13:25         ` m18063
2017-10-25  7:06         ` Zhi Mao
2017-10-25  7:06           ` Zhi Mao
2017-10-25  7:06           ` Zhi Mao

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.