* Re: [PATCH] Remove #ifdef CONFIG_64BIT from all asm-generic/fcntl.h
From: Palmer Dabbelt @ 2015-09-14 22:50 UTC (permalink / raw)
Cc: dhowells, arnd, 3chas3, hpa, mingo, plagnioj, jikos, linux-api,
linux-arch, linux-atm-general, linux-fbdev, linux-kernel, netdev,
tglx, tomi.valkeinen, x86
In-Reply-To: <18247.1441883885@warthog.procyon.org.uk>
On Thu, 10 Sep 2015 04:18:05 PDT (-0700), dhowells@redhat.com wrote:
> David Howells <dhowells@redhat.com> wrote:
>
>> Rather than iterating through all the rest of your patches and saying the same
>> thing, if there's something in a UAPI header that needs wrapping in __KERNEL__
>> to exclude it from userspace's use, then it should be transferred to the
>> non-UAPI variant of that header (which should #include the UAPI variant).
>
> I should mention that there is the odd case where this is difficult to
> achieve. See include/uapi/linux/acct.h for an example...
OK, sorry about that. I'm submitting a v3 that should fix these
problems.
^ permalink raw reply
* [PATCH v2] fbdev: omap2: connector-dvi: use of_get_i2c_adapter_by_node interface
From: Vladimir Zapolskiy @ 2015-09-15 13:12 UTC (permalink / raw)
To: linux-fbdev
This change is needed to properly lock I2C bus driver, which serves DDC.
Prior to this change i2c_put_adapter() is misused, which may lead to
an overflow over zero of I2C bus driver user counter.
Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
---
Changes from v1 to v2:
- none, v1 is http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354990.html
The original series http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354982.html
is separated to i2c, dri and fbdev parts, at the moment i2c part
with new of_get_i2c_adapter_by_node() interface has been applied.
drivers/video/fbdev/omap2/displays-new/connector-dvi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index a8ce920..d811e6d 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -294,7 +294,7 @@ static int dvic_probe_of(struct platform_device *pdev)
adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0);
if (adapter_node) {
- adapter = of_find_i2c_adapter_by_node(adapter_node);
+ adapter = of_get_i2c_adapter_by_node(adapter_node);
if (adapter = NULL) {
dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n");
omap_dss_put_device(ddata->in);
--
2.5.0
^ permalink raw reply related
* Re: [PATCH] staging: sm750fb: Added a space
From: Greg KH @ 2015-09-15 13:33 UTC (permalink / raw)
To: Anjali Menon
Cc: devel, linux-fbdev, teddy.wang, linux-kernel, sudipm.mukherjee
In-Reply-To: <1442228300-5167-1-git-send-email-cse.anjalimenon@gmail.com>
On Mon, Sep 14, 2015 at 04:28:20PM +0530, Anjali Menon wrote:
> Added a space to fix the following coding style error detected by
> checkpatch.
>
> ERROR: space required before the open parenthesis '('
>
> Signed-off-by: Anjali Menon <cse.anjalimenon@gmail.com>
> ---
> drivers/staging/sm750fb/ddk750_dvi.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
This patch doesn't apply to my tree at all, what did you make it
against?
greg k-h
^ permalink raw reply
* [RESEND PATCH] OMAPDSS: panel-sony-acx565akm: Export OF module alias information
From: Javier Martinez Canillas @ 2015-09-16 9:12 UTC (permalink / raw)
To: linux-kernel
Cc: Javier Martinez Canillas, linux-fbdev,
Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-omap
Drivers needs to export the OF id table and this be built into
the module or udev won't have the necessary information to autoload
the driver module when the device is registered via OF.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index 90cbc4c3406c..c581231c74a5 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -898,6 +898,7 @@ static const struct of_device_id acx565akm_of_match[] = {
{ .compatible = "omapdss,sony,acx565akm", },
{},
};
+MODULE_DEVICE_TABLE(of, acx565akm_of_match);
static struct spi_driver acx565akm_driver = {
.driver = {
--
2.4.3
^ permalink raw reply related
* [PATCH] pwm-backlight: fix the panel power sequence
From: YH Huang @ 2015-09-16 14:42 UTC (permalink / raw)
To: linux-arm-kernel
In order to match the panel power sequence, disable the enable_gpio
in the probe function. Also, reorder the code in the power_on and
power_off function to match the timing.
Signed-off-by: YH Huang <yh.huang@mediatek.com>
---
drivers/video/backlight/pwm_bl.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index eff379b..99eca1e 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -54,10 +54,11 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
if (err < 0)
dev_err(pb->dev, "failed to enable power supply\n");
+ pwm_enable(pb->pwm);
+
if (pb->enable_gpio)
gpiod_set_value(pb->enable_gpio, 1);
- pwm_enable(pb->pwm);
pb->enabled = true;
}
@@ -66,12 +67,12 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
if (!pb->enabled)
return;
- pwm_config(pb->pwm, 0, pb->period);
- pwm_disable(pb->pwm);
-
if (pb->enable_gpio)
gpiod_set_value(pb->enable_gpio, 0);
+ pwm_config(pb->pwm, 0, pb->period);
+ pwm_disable(pb->pwm);
+
regulator_disable(pb->power_supply);
pb->enabled = false;
}
@@ -241,8 +242,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->dev = &pdev->dev;
pb->enabled = false;
- pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
- GPIOD_OUT_HIGH);
+ pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable");
if (IS_ERR(pb->enable_gpio)) {
ret = PTR_ERR(pb->enable_gpio);
goto err_alloc;
@@ -264,6 +264,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
pb->enable_gpio = gpio_to_desc(data->enable_gpio);
}
+ if (pb->enable_gpio)
+ gpiod_direction_output(pb->enable_gpio, 0);
+
pb->power_supply = devm_regulator_get(&pdev->dev, "power");
if (IS_ERR(pb->power_supply)) {
ret = PTR_ERR(pb->power_supply);
--
1.7.9.5
^ permalink raw reply related
* Re: omapdss: Division by zero in kernel
From: Pavel Machek @ 2015-09-17 5:16 UTC (permalink / raw)
To: Pali Rohár
Cc: Peter Teoh, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Jyri Sarha, omap, linux-fbdev, LKML, Sebastian Reichel,
Aaro Koskinen, Tony Lindgren, Nishanth Menon
In-Reply-To: <20150819081139.GB15712@pali>
> > if (image->depth = 1) {
> > if (p->fix.visual = FB_VISUAL_TRUECOLOR ||
> > p->fix.visual = FB_VISUAL_DIRECTCOLOR) {
> > fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
> > bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
> > } else {
> > fgcolor = image->fg_color;
> > bgcolor = image->bg_color;
> > }
> >
> > if (32 % bpp = 0 && !start_index && !pitch_index &&
> > ((width & (32/bpp-1)) = 0) &&
> > bpp >= 8 && bpp <= 32)
> > fast_imageblit(image, p, dst1, fgcolor, bgcolor);
> > else
> > slow_imageblit(image, p, dst1, fgcolor, bgcolor,
> > start_index, pitch_index);
> > } else
> > color_imageblit(image, p, dst1, start_index, pitch_i
> >
> >
> > Notice that bpp is not checked for zero, and thus bpp=0 is totally
> > feasible? resulting in 32/bpp crashing the kernel?
> >
>
> Hm... this could really be a problem! But how to patch it? Which branch
> should be called (fast_ or slow_ function) if bpp is zero?
>
> And is there some way to force kernel to dump backtrace into dmesg when
> division by zero occur?
You can do WARN_ON(bpp=1) ... and should probably return in that
case.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Re: [RFC v4 17/25] powerpc, fbdev: Use arch_nvram_ops methods instead of nvram_read_byte() and nvram
From: Finn Thain @ 2015-09-18 8:17 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linux-kernel, linux-m68k, linuxppc-dev, Paul Mackerras,
Michael Ellerman, Arnd Bergmann, Greg Kroah-Hartman,
Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
In-Reply-To: <alpine.LNX.2.00.1507161530270.19651@nippy.intranet>
Hi Ben,
On Thu, 16 Jul 2015, I wrote:
> On Wed, 15 Jul 2015, I wrote:
>
> > On Tue, 14 Jul 2015, Benjamin Herrenschmidt wrote:
> >
> > > Maybe we should have a dedicated accessor for "mac_xpram" ...
> >
> ...
>
> The arch_nvram_ops methods don't deal with structures like partitions ...
Instead of the accessor you suggested, perhaps it would be better to add a
method like arch_nvram_ops.get_partition, to replace the
pmac_get_partition() exported function?
The call sites for pmac_get_partition() are in the implementation of the
IOC_NVRAM_GET_OFFSET ioctl that's used with /dev/nvram, and in
pmac_xpram_read(). pmac_xpram_write() has no caller and could be removed.
But this doesn't have much to do with linux-fbdev. I think the old
NV_CMODE/NV_VMODE issues*, which this patch avoids, are irrelevant to the
problem of nvram module re-use, which is the aim of this patch series.
But if those issues really are relevant then we should move the discussion
to the revised patch, that is, [RFC v6 16/25] powerpc, fbdev: Use NV_CMODE
and NV_VMODE only when CONFIG_PPC32 and CONFIG_PPC_PMAC and CONFIG_NVRAM.
(There was no response to any patch in RFC v6 from any PowerPC
maintainers, which is why I've revived this thread.)
* https://lists.ozlabs.org/pipermail/linuxppc-dev/2001-November/012662.html
--
^ permalink raw reply
* [PATCH] fbdev: broadsheetfb: fix memory leak
From: Sudip Mukherjee @ 2015-09-18 11:28 UTC (permalink / raw)
To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
Cc: linux-kernel, linux-fbdev, Sudip Mukherjee
On the error path we have missed releasing the firmware.
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
drivers/video/fbdev/broadsheetfb.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c
index 0e5fde1..ac1f41e 100644
--- a/drivers/video/fbdev/broadsheetfb.c
+++ b/drivers/video/fbdev/broadsheetfb.c
@@ -752,7 +752,7 @@ static ssize_t broadsheet_loadstore_waveform(struct device *dev,
if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) {
dev_err(dev, "Invalid waveform\n");
err = -EINVAL;
- goto err_failed;
+ goto err_fw;
}
mutex_lock(&(par->io_lock));
@@ -762,13 +762,15 @@ static ssize_t broadsheet_loadstore_waveform(struct device *dev,
mutex_unlock(&(par->io_lock));
if (err < 0) {
dev_err(dev, "Failed to store broadsheet waveform\n");
- goto err_failed;
+ goto err_fw;
}
dev_info(dev, "Stored broadsheet waveform, size %zd\n", fw_entry->size);
return len;
+err_fw:
+ release_firmware(fw_entry);
err_failed:
return err;
}
--
1.9.1
^ permalink raw reply related
* [PATCH] omapdss: acx565akm: Fix module autoload for OF platform driver
From: Luis de Bethencourt @ 2015-09-18 18:44 UTC (permalink / raw)
To: linux-kernel
Cc: Tomi Valkeinen, Jean-Christophe Plagniol-Villard, linux-omap,
linux-fbdev
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.
Signed-off-by: Luis de Bethencourt <luisbg@osg.samsung.com>
---
Hello,
This patch adds the missing MODULE_DEVICE_TABLE() for OF to export
that information so modules have the correct aliases built-in and
autoloading works correctly.
A longer explanation by Javier Canillas can be found here:
https://lkml.org/lkml/2015/7/30/519
Thanks,
Luis
drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index 90cbc4c..c581231 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -898,6 +898,7 @@ static const struct of_device_id acx565akm_of_match[] = {
{ .compatible = "omapdss,sony,acx565akm", },
{},
};
+MODULE_DEVICE_TABLE(of, acx565akm_of_match);
static struct spi_driver acx565akm_driver = {
.driver = {
--
2.4.6
^ permalink raw reply related
* [PATCH] video: fbdev: mb862xx: Fix module autoload for OF platform driver
From: Luis de Bethencourt @ 2015-09-18 18:46 UTC (permalink / raw)
To: linux-kernel
Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Wolfram Sang,
linux-fbdev
This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.
Signed-off-by: Luis de Bethencourt <luisbg@osg.samsung.com>
---
Hello,
This patch adds the missing MODULE_DEVICE_TABLE() for OF to export
that information so modules have the correct aliases built-in and
autoloading works correctly.
A longer explanation by Javier Canillas can be found here:
https://lkml.org/lkml/2015/7/30/519
Thanks,
Luis
drivers/video/fbdev/mb862xx/mb862xxfbdrv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
index 9b8bebd..f9ec5c0 100644
--- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
@@ -831,6 +831,7 @@ static struct of_device_id of_platform_mb862xx_tbl[] = {
{ .compatible = "fujitsu,coral", },
{ /* end */ }
};
+MODULE_DEVICE_TABLE(of, of_platform_mb862xx_tbl);
static struct platform_driver of_platform_mb862xxfb_driver = {
.driver = {
--
2.4.6
^ permalink raw reply related
* Re: [PATCH] backlight: lp855x: Make sure props struct is zeroed
From: Lee Jones @ 2015-09-19 10:06 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Milo Kim, Jingoo Han, Jean-Christophe Plagniol-Villard,
Tomi Valkeinen, linux-fbdev, linux-kernel, Werner Johansson
In-Reply-To: <1440697275-4469-1-git-send-email-bjorn.andersson@sonymobile.com>
On Thu, 27 Aug 2015, Bjorn Andersson wrote:
> From: Werner Johansson <werner.johansson@sonymobile.com>
>
> The driver occasionally got stuck in suspend mode or other strange
> states as those parts of the props struct were never initialized.
>
> Signed-off-by: Werner Johansson <werner.johansson@sonymobile.com>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
> ---
> drivers/video/backlight/lp855x_bl.c | 1 +
> 1 file changed, 1 insertion(+)
Applied, thanks.
> diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
> index 88116b493f3b..0a7f88ce1ab0 100644
> --- a/drivers/video/backlight/lp855x_bl.c
> +++ b/drivers/video/backlight/lp855x_bl.c
> @@ -282,6 +282,7 @@ static int lp855x_backlight_register(struct lp855x *lp)
> struct lp855x_platform_data *pdata = lp->pdata;
> const char *name = pdata->name ? : DEFAULT_BL_NAME;
>
> + memset(&props, 0, sizeof(props));
> props.type = BACKLIGHT_PLATFORM;
> props.max_brightness = MAX_BRIGHTNESS;
>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH 1/2] backlight: adp8860: Remove unnecessary MODULE_ALIAS()
From: Lee Jones @ 2015-09-20 4:20 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel, linux-fbdev, Michael Hennerich, Tomi Valkeinen,
Jingoo Han, Jean-Christophe Plagniol-Villard
In-Reply-To: <1440970465-11651-1-git-send-email-javier@osg.samsung.com>
On Sun, 30 Aug 2015, Javier Martinez Canillas wrote:
> The driver has a I2C device id table that is used to create the modaliases
> and also "adp8860-backlight" is not a supported I2C id, so it's never used.
>
> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
>
> ---
>
> drivers/video/backlight/adp8860_bl.c | 1 -
> 1 file changed, 1 deletion(-)
Applied, thanks.
> diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
> index 71147f4461b8..98ffe71e8af2 100644
> --- a/drivers/video/backlight/adp8860_bl.c
> +++ b/drivers/video/backlight/adp8860_bl.c
> @@ -819,4 +819,3 @@ module_i2c_driver(adp8860_driver);
> MODULE_LICENSE("GPL v2");
> MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
> MODULE_DESCRIPTION("ADP8860 Backlight driver");
> -MODULE_ALIAS("i2c:adp8860-backlight");
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH 2/2] backlight: adp8870: Remove unnecessary MODULE_ALIAS()
From: Lee Jones @ 2015-09-20 4:20 UTC (permalink / raw)
To: Javier Martinez Canillas
Cc: linux-kernel, linux-fbdev, Tomi Valkeinen, Jingoo Han,
Jean-Christophe Plagniol-Villard
In-Reply-To: <1440970465-11651-2-git-send-email-javier@osg.samsung.com>
On Sun, 30 Aug 2015, Javier Martinez Canillas wrote:
> The driver has a I2C device id table that is used to create the modaliases
> and also "adp8870-backlight" is not a supported I2C id, so it's never used.
>
> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
>
> ---
>
> drivers/video/backlight/adp8870_bl.c | 1 -
> 1 file changed, 1 deletion(-)
Applied, thanks.
> diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
> index 037e43083343..9d738352d7d4 100644
> --- a/drivers/video/backlight/adp8870_bl.c
> +++ b/drivers/video/backlight/adp8870_bl.c
> @@ -992,4 +992,3 @@ module_i2c_driver(adp8870_driver);
> MODULE_LICENSE("GPL v2");
> MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
> MODULE_DESCRIPTION("ADP8870 Backlight driver");
> -MODULE_ALIAS("i2c:adp8870-backlight");
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v3 00/12] pwm: add support for atomic update
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This series adds support for atomic PWM update, or IOW, the capability
to update all the parameters of a PWM device (enabled/disabled, period,
duty and polarity) in one go.
Best Regards,
Boris
Changes since v2:
- rebased on top of 4.3-rc2
- reintroduced pwm-regulator patches
Changes since v1:
- dropped applied patches
- squashed Heiko's fixes into the rockchip driver changes
- made a few cosmetic changes
- added kerneldoc comments
- added Heiko's patch to display more information in debugfs
- dropped pwm-regulator patches (should be submitted separately)
Boris Brezillon (11):
pwm: introduce default period and polarity concepts
pwm: define a new pwm_state struct
pwm: move the enabled/disabled info to pwm_state struct
backlight: pwm_bl: remove useless call to pwm_set_period
pwm: declare a default PWM state
pwm: add the PWM initial state retrieval infra
pwm: add the core infrastructure to allow atomic update
pwm: rockchip: add initial state retrieval
pwm: rockchip: add support for atomic update
regulator: pwm: implement ->enable(), ->disable() and ->is_enabled
methods
regulator: pwm: properly initialize the ->state field
Heiko Stübner (1):
pwm: add information about polarity, duty cycle and period to debugfs
drivers/leds/leds-pwm.c | 2 +-
drivers/pwm/core.c | 169 +++++++++++++++++++++++++++++++----
drivers/pwm/pwm-pxa.c | 2 +-
drivers/pwm/pwm-rockchip.c | 119 +++++++++++++++++++-----
drivers/pwm/pwm-sun4i.c | 3 +-
drivers/regulator/pwm-regulator.c | 65 ++++++++++++--
drivers/video/backlight/lm3630a_bl.c | 4 +-
drivers/video/backlight/pwm_bl.c | 10 ++-
drivers/video/fbdev/ssd1307fb.c | 2 +-
include/linux/pwm.h | 89 +++++++++++++++---
10 files changed, 392 insertions(+), 73 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH v3 01/12] pwm: introduce default period and polarity concepts
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
When requested by a user, the PWM is assigned a default period and polarity
extracted from the DT, the platform data or statically set by the driver.
Those default values are currently stored in the period and polarity
fields of the pwm_device struct, but they will be stored somewhere else
once we have introduced the architecture allowing for hardware state
retrieval.
The pwm_set_default_polarity and pwm_set_default_period should only be
used by PWM drivers or the PWM core infrastructure to specify the
default period and polarity values.
PWM users might call the pwm_get_default_period to query the default
period value. There is currently no helper to query the default
polarity, but it might be added later on if there is a need for it.
This patch also modifies all the places where the default helpers should
be used in place of the standard ones.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/leds/leds-pwm.c | 2 +-
drivers/pwm/core.c | 14 +++++++-------
drivers/pwm/pwm-pxa.c | 2 +-
drivers/pwm/pwm-sun4i.c | 3 ++-
drivers/regulator/pwm-regulator.c | 4 ++--
drivers/video/backlight/lm3630a_bl.c | 4 ++--
drivers/video/backlight/pwm_bl.c | 2 +-
drivers/video/fbdev/ssd1307fb.c | 2 +-
include/linux/pwm.h | 17 +++++++++++++++++
9 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 1d07e3e..2c564d1 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -125,7 +125,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
if (led_data->can_sleep)
INIT_WORK(&led_data->work, led_pwm_work);
- led_data->period = pwm_get_period(led_data->pwm);
+ led_data->period = pwm_get_default_period(led_data->pwm);
if (!led_data->period && (led->pwm_period_ns > 0))
led_data->period = led->pwm_period_ns;
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 3f9df3e..732375d 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -146,12 +146,12 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[1]);
+ pwm_set_default_period(pwm, args->args[1]);
if (args->args[2] & PWM_POLARITY_INVERTED)
- pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
+ pwm_set_default_polarity(pwm, PWM_POLARITY_INVERSED);
else
- pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
+ pwm_set_default_polarity(pwm, PWM_POLARITY_NORMAL);
return pwm;
}
@@ -172,7 +172,7 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[1]);
+ pwm_set_default_period(pwm, args->args[1]);
return pwm;
}
@@ -268,7 +268,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->chip = chip;
pwm->pwm = chip->base + i;
pwm->hwpwm = i;
- pwm->polarity = polarity;
+ pwm_set_default_polarity(pwm, polarity);
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
@@ -730,8 +730,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
if (IS_ERR(pwm))
goto out;
- pwm_set_period(pwm, chosen->period);
- pwm_set_polarity(pwm, chosen->polarity);
+ pwm_set_default_period(pwm, chosen->period);
+ pwm_set_default_polarity(pwm, chosen->polarity);
out:
mutex_unlock(&pwm_lookup_lock);
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index cb2f702..65b80aa 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -160,7 +160,7 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[0]);
+ pwm_set_default_period(pwm, args->args[0]);
return pwm;
}
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index cd9dde5..a364fb7 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -333,7 +333,8 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
for (i = 0; i < pwm->chip.npwm; i++)
if (!(val & BIT_CH(PWM_ACT_STATE, i)))
- pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED;
+ pwm_set_default_polarity(&pwm->chip.pwms[i],
+ PWM_POLARITY_INVERSED);
clk_disable_unprepare(pwm->clk);
return 0;
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index fc3166d..cc549b7 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -56,7 +56,7 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
int dutycycle;
int ret;
- pwm_reg_period = pwm_get_period(drvdata->pwm);
+ pwm_reg_period = pwm_get_default_period(drvdata->pwm);
dutycycle = (pwm_reg_period *
drvdata->duty_cycle_table[selector].dutycycle) / 100;
@@ -114,7 +114,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
unsigned int ramp_delay = rdev->constraints->ramp_delay;
- unsigned int period = pwm_get_period(drvdata->pwm);
+ unsigned int period = pwm_get_default_period(drvdata->pwm);
int duty_cycle;
int ret;
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 35fe482..449ebc3 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -162,7 +162,7 @@ static int lm3630a_intr_config(struct lm3630a_chip *pchip)
static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max)
{
- unsigned int period = pwm_get_period(pchip->pwmd);
+ unsigned int period = pwm_get_default_period(pchip->pwmd);
unsigned int duty = br * period / br_max;
pwm_config(pchip->pwmd, duty, period);
@@ -425,7 +425,7 @@ static int lm3630a_probe(struct i2c_client *client,
return PTR_ERR(pchip->pwmd);
}
}
- pchip->pwmd->period = pdata->pwm_period;
+ pwm_set_default_period(pchip->pwmd, pdata->pwm_period);
/* interrupt enable : irq 0 is not allowed */
pchip->irq = client->irq;
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index eff379b..ae498c1 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -294,7 +294,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
* set the period from platform data if it has not already been set
* via the PWM lookup table.
*/
- pb->period = pwm_get_period(pb->pwm);
+ pb->period = pwm_get_default_period(pb->pwm);
if (!pb->period && (data->pwm_period_ns > 0)) {
pb->period = data->pwm_period_ns;
pwm_set_period(pb->pwm, data->pwm_period_ns);
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 93f4c90..ab3daf0 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -294,7 +294,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
return PTR_ERR(par->pwm);
}
- par->pwm_period = pwm_get_period(par->pwm);
+ par->pwm_period = pwm_get_default_period(par->pwm);
/* Enable the PWM */
pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
pwm_enable(par->pwm);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index d681f68..31239a9 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -115,11 +115,22 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
pwm->period = period;
}
+static inline void pwm_set_default_period(struct pwm_device *pwm,
+ unsigned int period)
+{
+ pwm_set_period(pwm, period);
+}
+
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
{
return pwm ? pwm->period : 0;
}
+static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
+{
+ return pwm_get_period(pwm);
+}
+
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
{
if (pwm)
@@ -136,6 +147,12 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
*/
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+static inline void pwm_set_default_polarity(struct pwm_device *pwm,
+ enum pwm_polarity polarity)
+{
+ pwm_set_polarity(pwm, polarity);
+}
+
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
{
return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 02/12] pwm: define a new pwm_state struct
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
The PWM state, represented by its period, duty_cycle and polarity,
is currently directly stored in the PWM device.
Declare a pwm_state structure embedding those field so that we can later
use this struct to atomically update all the PWM parameters at once.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 6 +++---
include/linux/pwm.h | 30 +++++++++++++++++++-----------
2 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 732375d..09037de 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -446,8 +446,8 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
if (err)
return err;
- pwm->duty_cycle = duty_ns;
- pwm->period = period_ns;
+ pwm->state.duty_cycle = duty_ns;
+ pwm->state.period = period_ns;
return 0;
}
@@ -480,7 +480,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
if (err)
return err;
- pwm->polarity = polarity;
+ pwm->state.polarity = polarity;
return 0;
}
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 31239a9..e0e0ed8 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -79,6 +79,18 @@ enum {
PWMF_EXPORTED = 1 << 2,
};
+/*
+ * struct pwm_state - state of a PWM channel
+ * @period: PWM period (in nanoseconds)
+ * @duty_cycle: PWM duty cycle (in nanoseconds)
+ * @polarity: PWM polarity
+ */
+struct pwm_state {
+ unsigned int period;
+ unsigned int duty_cycle;
+ enum pwm_polarity polarity;
+};
+
/**
* struct pwm_device - PWM channel object
* @label: name of the PWM device
@@ -87,9 +99,7 @@ enum {
* @pwm: global index of the PWM device
* @chip: PWM chip providing this PWM device
* @chip_data: chip-private data associated with the PWM device
- * @period: period of the PWM signal (in nanoseconds)
- * @duty_cycle: duty cycle of the PWM signal (in nanoseconds)
- * @polarity: polarity of the PWM signal
+ * @state: curent PWM channel state
*/
struct pwm_device {
const char *label;
@@ -99,9 +109,7 @@ struct pwm_device {
struct pwm_chip *chip;
void *chip_data;
- unsigned int period;
- unsigned int duty_cycle;
- enum pwm_polarity polarity;
+ struct pwm_state state;
};
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
@@ -112,7 +120,7 @@ static inline bool pwm_is_enabled(const struct pwm_device *pwm)
static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
{
if (pwm)
- pwm->period = period;
+ pwm->state.period = period;
}
static inline void pwm_set_default_period(struct pwm_device *pwm,
@@ -123,7 +131,7 @@ static inline void pwm_set_default_period(struct pwm_device *pwm,
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
{
- return pwm ? pwm->period : 0;
+ return pwm ? pwm->state.period : 0;
}
static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
@@ -134,12 +142,12 @@ static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
{
if (pwm)
- pwm->duty_cycle = duty;
+ pwm->state.duty_cycle = duty;
}
static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
{
- return pwm ? pwm->duty_cycle : 0;
+ return pwm ? pwm->state.duty_cycle : 0;
}
/*
@@ -155,7 +163,7 @@ static inline void pwm_set_default_polarity(struct pwm_device *pwm,
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
{
- return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
+ return pwm ? pwm->state.polarity : PWM_POLARITY_NORMAL;
}
/**
--
1.9.1
^ permalink raw reply related
* [PATCH v3 03/12] pwm: move the enabled/disabled info to pwm_state struct
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Prepare the transition to PWM atomic update by moving the enabled/disabled
state into the pwm_state struct. This way we can easily update the whole
PWM state by copying the new state in the ->state field.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 15 ++++++++++++---
include/linux/pwm.h | 7 ++++---
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 09037de..963238c3 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -494,8 +494,15 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
*/
int pwm_enable(struct pwm_device *pwm)
{
- if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
- return pwm->chip->ops->enable(pwm->chip, pwm);
+ if (pwm && !pwm_is_enabled(pwm)) {
+ int err;
+
+ err = pwm->chip->ops->enable(pwm->chip, pwm);
+ if (!err)
+ pwm->state.enabled = true;
+
+ return err;
+ }
return pwm ? 0 : -EINVAL;
}
@@ -507,8 +514,10 @@ EXPORT_SYMBOL_GPL(pwm_enable);
*/
void pwm_disable(struct pwm_device *pwm)
{
- if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm && pwm_is_enabled(pwm)) {
pwm->chip->ops->disable(pwm->chip, pwm);
+ pwm->state.enabled = false;
+ }
}
EXPORT_SYMBOL_GPL(pwm_disable);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index e0e0ed8..433a097 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -75,8 +75,7 @@ enum pwm_polarity {
enum {
PWMF_REQUESTED = 1 << 0,
- PWMF_ENABLED = 1 << 1,
- PWMF_EXPORTED = 1 << 2,
+ PWMF_EXPORTED = 1 << 1,
};
/*
@@ -84,11 +83,13 @@ enum {
* @period: PWM period (in nanoseconds)
* @duty_cycle: PWM duty cycle (in nanoseconds)
* @polarity: PWM polarity
+ * @enabled: PWM enabled status
*/
struct pwm_state {
unsigned int period;
unsigned int duty_cycle;
enum pwm_polarity polarity;
+ bool enabled;
};
/**
@@ -114,7 +115,7 @@ struct pwm_device {
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
{
- return test_bit(PWMF_ENABLED, &pwm->flags);
+ return pwm->state.enabled;
}
static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
--
1.9.1
^ permalink raw reply related
* [PATCH v3 04/12] backlight: pwm_bl: remove useless call to pwm_set_period
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
The PWM period will be set when calling pwm_config. Remove this useless
call to pwm_set_period, which might mess up with the initial PWM state
once we have added proper support for PWM init state retrieval.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/video/backlight/pwm_bl.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ae498c1..71944f8 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -293,12 +293,14 @@ static int pwm_backlight_probe(struct platform_device *pdev)
* period, parsed from the DT, in the PWM device. For the non-DT case,
* set the period from platform data if it has not already been set
* via the PWM lookup table.
+ * FIXME: This assignment should be dropped as soon as all the boards
+ * have moved to the PWM lookup table approach. The same goes for the
+ * pb->period field which should be replaced by
+ * pwm_get_default_period() calls.
*/
pb->period = pwm_get_default_period(pb->pwm);
- if (!pb->period && (data->pwm_period_ns > 0)) {
+ if (!pb->period && (data->pwm_period_ns > 0))
pb->period = data->pwm_period_ns;
- pwm_set_period(pb->pwm, data->pwm_period_ns);
- }
pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 05/12] pwm: declare a default PWM state
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Prepare the addition of the PWM initial state retrieval by adding a default
state where all the parameters retrieved from DT, platform data or
statically forced by the hardware will be stored.
Once done we will be able to store the initial state in the ->state field
without risking to loose the default parameters.
Update the pwm_set/get_default_xxx helpers accordingly.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
include/linux/pwm.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 433a097..f8cc460 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -101,6 +101,7 @@ struct pwm_state {
* @chip: PWM chip providing this PWM device
* @chip_data: chip-private data associated with the PWM device
* @state: curent PWM channel state
+ * @default_state: default PWM channel state
*/
struct pwm_device {
const char *label;
@@ -111,6 +112,7 @@ struct pwm_device {
void *chip_data;
struct pwm_state state;
+ struct pwm_state default_state;
};
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
@@ -127,7 +129,8 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
static inline void pwm_set_default_period(struct pwm_device *pwm,
unsigned int period)
{
- pwm_set_period(pwm, period);
+ if (pwm)
+ pwm->default_state.period = period;
}
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
@@ -137,7 +140,7 @@ static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
{
- return pwm_get_period(pwm);
+ return pwm ? pwm->default_state.period : 0;
}
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
@@ -159,7 +162,8 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
static inline void pwm_set_default_polarity(struct pwm_device *pwm,
enum pwm_polarity polarity)
{
- pwm_set_polarity(pwm, polarity);
+ if (pwm)
+ pwm->default_state.polarity = polarity;
}
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
--
1.9.1
^ permalink raw reply related
* [PATCH v3 06/12] pwm: add the PWM initial state retrieval infra
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Add a ->reset_state() function to the pwm_ops struct to let PWM drivers
initialize the PWM state attached to a PWM device.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 3 +++
include/linux/pwm.h | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 963238c3..60ad758 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -270,6 +270,9 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->hwpwm = i;
pwm_set_default_polarity(pwm, polarity);
+ if (chip->ops->reset_state)
+ chip->ops->reset_state(chip, pwm);
+
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index f8cc460..cddb12b 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -179,6 +179,9 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
* @set_polarity: configure the polarity of this PWM
* @enable: enable PWM output toggling
* @disable: disable PWM output toggling
+ * @reset_state: reset the current PWM state (pwm->state) to the actual
+ * hardware state. This function is only called once per
+ * PWM device when the PWM chip is registered.
* @dbg_show: optional routine to show contents in debugfs
* @owner: helps prevent removal of modules exporting active PWMs
*/
@@ -191,6 +194,7 @@ struct pwm_ops {
enum pwm_polarity polarity);
int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+ void (*reset_state)(struct pwm_chip *chip, struct pwm_device *pwm);
#ifdef CONFIG_DEBUG_FS
void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s);
#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v3 07/12] pwm: add the core infrastructure to allow atomic update
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Add an ->apply() method to the pwm_ops struct to allow PWM drivers to
implement atomic update.
This method will be preferred over the ->enable(), ->disable() and
->config() methods if available.
Add the pwm_get_state(), pwm_get_default_state() and pwm_apply_state()
functions for PWM users to be able to use the atomic update feature.
Note that the pwm_apply_state() does not guarantee the atomicity of the
update operation, it all depends on the availability and implementation
of the ->apply() method.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++-----
include/linux/pwm.h | 27 ++++++++++
2 files changed, 157 insertions(+), 12 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 60ad758..ff3c662 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -46,6 +46,12 @@ static struct pwm_device *pwm_to_device(unsigned int pwm)
return radix_tree_lookup(&pwm_tree, pwm);
}
+static void pwm_set_state(struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ pwm->state = *state;
+}
+
static int alloc_pwms(int pwm, unsigned int count)
{
unsigned int from = 0;
@@ -226,6 +232,19 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
}
EXPORT_SYMBOL_GPL(pwm_get_chip_data);
+static bool pwm_ops_check(const struct pwm_ops *ops)
+{
+ /* driver supports legacy, non-atomic operation */
+ if (ops->config && ops->enable && ops->disable)
+ return true;
+
+ /* driver supports atomic operation */
+ if (ops->apply)
+ return true;
+
+ return false;
+}
+
/**
* pwmchip_add_with_polarity() - register a new PWM chip
* @chip: the PWM chip to add
@@ -244,8 +263,10 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
unsigned int i;
int ret;
- if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
- !chip->ops->enable || !chip->ops->disable || !chip->npwm)
+ if (!chip || !chip->dev || !chip->ops || !chip->npwm)
+ return -EINVAL;
+
+ if (!pwm_ops_check(chip->ops))
return -EINVAL;
mutex_lock(&pwm_lock);
@@ -445,7 +466,19 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
return -EINVAL;
- err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
+ if (pwm->chip->ops->apply) {
+ struct pwm_state state;
+
+ pwm_get_state(pwm, &state);
+ state.period = period_ns;
+ state.duty_cycle = duty_ns;
+
+ err = pwm->chip->ops->apply(pwm->chip, pwm, &state);
+ } else {
+ err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns,
+ period_ns);
+ }
+
if (err)
return err;
@@ -473,6 +506,18 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
if (!pwm || !pwm->chip->ops)
return -EINVAL;
+ if (pwm->chip->ops->apply) {
+ struct pwm_state state;
+
+ pwm_get_state(pwm, &state);
+ state.polarity = polarity;
+ err = pwm->chip->ops->apply(pwm->chip, pwm, &state);
+ if (!err)
+ pwm->state.polarity = polarity;
+
+ return err;
+ }
+
if (!pwm->chip->ops->set_polarity)
return -ENOSYS;
@@ -497,17 +542,29 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
*/
int pwm_enable(struct pwm_device *pwm)
{
- if (pwm && !pwm_is_enabled(pwm)) {
- int err;
+ int err;
- err = pwm->chip->ops->enable(pwm->chip, pwm);
- if (!err)
- pwm->state.enabled = true;
+ if (!pwm)
+ return -EINVAL;
- return err;
+ if (pwm_is_enabled(pwm))
+ return 0;
+
+ if (pwm->chip->ops->apply) {
+ struct pwm_state state;
+
+ pwm_get_state(pwm, &state);
+ state.enabled = true;
+
+ err = pwm->chip->ops->apply(pwm->chip, pwm, &state);
+ } else {
+ err = pwm->chip->ops->enable(pwm->chip, pwm);
}
- return pwm ? 0 : -EINVAL;
+ if (!err)
+ pwm->state.enabled = true;
+
+ return err;
}
EXPORT_SYMBOL_GPL(pwm_enable);
@@ -517,13 +574,74 @@ EXPORT_SYMBOL_GPL(pwm_enable);
*/
void pwm_disable(struct pwm_device *pwm)
{
- if (pwm && pwm_is_enabled(pwm)) {
+ if (!pwm || !pwm_is_enabled(pwm))
+ return;
+
+ if (pwm->chip->ops->apply) {
+ struct pwm_state state;
+
+ pwm_get_state(pwm, &state);
+ state.enabled = false;
+
+ pwm->chip->ops->apply(pwm->chip, pwm, &state);
+ } else {
pwm->chip->ops->disable(pwm->chip, pwm);
- pwm->state.enabled = false;
}
+
+ pwm->state.enabled = false;
}
EXPORT_SYMBOL_GPL(pwm_disable);
+/**
+ * pwm_apply_state() - atomically apply a new state to a PWM device
+ * @pwm: PWM device
+ * @state: new state to apply
+ */
+int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
+{
+ int err = 0;
+
+ if (!pwm)
+ return -EINVAL;
+
+ if (!memcmp(state, &pwm->state, sizeof(*state)))
+ return 0;
+
+ if (pwm->chip->ops->apply) {
+ err = pwm->chip->ops->apply(pwm->chip, pwm, state);
+ if (!err)
+ pwm_set_state(pwm, state);
+ } else {
+ /*
+ * FIXME: restore the initial state in case of error.
+ */
+ if (state->polarity != pwm->state.polarity) {
+ pwm_disable(pwm);
+ err = pwm_set_polarity(pwm, state->polarity);
+ if (err)
+ goto out;
+ }
+
+ if (state->period != pwm->state.period ||
+ state->duty_cycle != pwm->state.duty_cycle) {
+ err = pwm_config(pwm, state->period, state->duty_cycle);
+ if (err)
+ goto out;
+ }
+
+ if (state->enabled != pwm->state.enabled) {
+ if (state->enabled)
+ err = pwm_enable(pwm);
+ else
+ pwm_disable(pwm);
+ }
+ }
+
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(pwm_apply_state);
+
static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
{
struct pwm_chip *chip;
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index cddb12b..11ee041 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -171,6 +171,30 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
return pwm ? pwm->state.polarity : PWM_POLARITY_NORMAL;
}
+int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state);
+
+/**
+ * pwm_get_state() - retrieve the current PWM state
+ * @pwm: PWM device
+ * @state: state to fill with the current PWM state
+ */
+static inline void pwm_get_state(struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ *state = pwm->state;
+}
+
+/**
+ * pwm_get_default_state() - retrieve the default PWM state
+ * @pwm: PWM device
+ * @state: state to fill with the default PWM state
+ */
+static inline void pwm_get_default_state(struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ *state = pwm->default_state;
+}
+
/**
* struct pwm_ops - PWM controller operations
* @request: optional hook for requesting a PWM
@@ -179,6 +203,7 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
* @set_polarity: configure the polarity of this PWM
* @enable: enable PWM output toggling
* @disable: disable PWM output toggling
+ * @apply: atomically apply a new PWM config
* @reset_state: reset the current PWM state (pwm->state) to the actual
* hardware state. This function is only called once per
* PWM device when the PWM chip is registered.
@@ -194,6 +219,8 @@ struct pwm_ops {
enum pwm_polarity polarity);
int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
+ int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state);
void (*reset_state)(struct pwm_chip *chip, struct pwm_device *pwm);
#ifdef CONFIG_DEBUG_FS
void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 08/12] pwm: add information about polarity, duty cycle and period to debugfs
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
From: Heiko Stübner <heiko@sntech.de>
The pwm-states make it possible to also output the polarity, duty cycle
and period information in the debugfs pwm summary-outout.
This makes it easier to gather overview information about pwms without
needing to walk through the sysfs attributes of every pwm.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index ff3c662..7eba2f3 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -1018,6 +1018,11 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
if (pwm_is_enabled(pwm))
seq_puts(s, " enabled");
+ seq_printf(s, " period:%uns", pwm_get_period(pwm));
+ seq_printf(s, " duty:%uns", pwm_get_duty_cycle(pwm));
+ seq_printf(s, " polarity:%s", pwm_get_polarity(pwm) ? "inverse"
+ : "normal");
+
seq_puts(s, "\n");
}
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 09/12] pwm: rockchip: add initial state retrieval
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Implement the ->reset_state() function to expose initial state.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/pwm-rockchip.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 7d9cc90..6eab25c 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -51,6 +51,7 @@ struct rockchip_pwm_data {
void (*set_enable)(struct pwm_chip *chip,
struct pwm_device *pwm, bool enable);
+ void (*reset_state)(struct pwm_chip *chip, struct pwm_device *pwm);
};
static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
@@ -75,6 +76,18 @@ static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
}
+static void rockchip_pwm_reset_state_v1(struct pwm_chip *chip,
+ struct pwm_device *pwm)
+{
+ struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+ u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
+ u32 val;
+
+ val = readl(pc->base + pc->data->regs.ctrl);
+ if ((val & enable_conf) = enable_conf)
+ pwm->state.enabled = true;
+}
+
static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
struct pwm_device *pwm, bool enable)
{
@@ -98,6 +111,54 @@ static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
writel_relaxed(val, pc->base + pc->data->regs.ctrl);
}
+static void rockchip_pwm_reset_state_v2(struct pwm_chip *chip,
+ struct pwm_device *pwm)
+{
+ struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+ u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
+ PWM_CONTINUOUS;
+ u32 val;
+
+ val = readl(pc->base + pc->data->regs.ctrl);
+ if ((val & enable_conf) != enable_conf)
+ return;
+
+ pwm->state.enabled = true;
+
+ if (!(val & PWM_DUTY_POSITIVE))
+ pwm->state.polarity = PWM_POLARITY_INVERSED;
+}
+
+static void rockchip_pwm_reset_state(struct pwm_chip *chip,
+ struct pwm_device *pwm)
+{
+ struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+ unsigned long clk_rate;
+ u64 tmp;
+ int ret;
+
+ ret = clk_enable(pc->clk);
+ if (ret)
+ return;
+
+ clk_rate = clk_get_rate(pc->clk);
+
+ tmp = readl(pc->base + pc->data->regs.period);
+ tmp *= pc->data->prescaler * NSEC_PER_SEC;
+ do_div(tmp, clk_rate);
+ pwm->state.period = tmp;
+
+ tmp = readl(pc->base + pc->data->regs.duty);
+ tmp *= pc->data->prescaler * NSEC_PER_SEC;
+ do_div(tmp, clk_rate);
+ pwm->state.duty_cycle = tmp;
+
+ pc->data->reset_state(chip, chip->pwms);
+
+ if (!pwm_is_enabled(pwm))
+ clk_disable(pc->clk);
+}
+
static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
{
@@ -171,6 +232,7 @@ static void rockchip_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
}
static const struct pwm_ops rockchip_pwm_ops_v1 = {
+ .reset_state = rockchip_pwm_reset_state,
.config = rockchip_pwm_config,
.enable = rockchip_pwm_enable,
.disable = rockchip_pwm_disable,
@@ -178,6 +240,7 @@ static const struct pwm_ops rockchip_pwm_ops_v1 = {
};
static const struct pwm_ops rockchip_pwm_ops_v2 = {
+ .reset_state = rockchip_pwm_reset_state,
.config = rockchip_pwm_config,
.set_polarity = rockchip_pwm_set_polarity,
.enable = rockchip_pwm_enable,
@@ -195,6 +258,7 @@ static const struct rockchip_pwm_data pwm_data_v1 = {
.prescaler = 2,
.ops = &rockchip_pwm_ops_v1,
.set_enable = rockchip_pwm_set_enable_v1,
+ .reset_state = rockchip_pwm_reset_state_v1,
};
static const struct rockchip_pwm_data pwm_data_v2 = {
@@ -207,6 +271,7 @@ static const struct rockchip_pwm_data pwm_data_v2 = {
.prescaler = 1,
.ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
+ .reset_state = rockchip_pwm_reset_state_v2,
};
static const struct rockchip_pwm_data pwm_data_vop = {
@@ -219,6 +284,7 @@ static const struct rockchip_pwm_data pwm_data_vop = {
.prescaler = 1,
.ops = &rockchip_pwm_ops_v2,
.set_enable = rockchip_pwm_set_enable_v2,
+ .reset_state = rockchip_pwm_reset_state_v2,
};
static const struct of_device_id rockchip_pwm_dt_ids[] = {
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/12] pwm: rockchip: add support for atomic update
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Implement the ->apply() function to add support for atomic update.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/pwm-rockchip.c | 53 +++++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 24 deletions(-)
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 6eab25c..48b814d 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -50,7 +50,8 @@ struct rockchip_pwm_data {
const struct pwm_ops *ops;
void (*set_enable)(struct pwm_chip *chip,
- struct pwm_device *pwm, bool enable);
+ struct pwm_device *pwm, bool enable,
+ enum pwm_polarity polarity);
void (*reset_state)(struct pwm_chip *chip, struct pwm_device *pwm);
};
@@ -60,7 +61,8 @@ static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip *c)
}
static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
- struct pwm_device *pwm, bool enable)
+ struct pwm_device *pwm, bool enable,
+ enum pwm_polarity polarity)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
@@ -89,14 +91,15 @@ static void rockchip_pwm_reset_state_v1(struct pwm_chip *chip,
}
static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
- struct pwm_device *pwm, bool enable)
+ struct pwm_device *pwm, bool enable,
+ enum pwm_polarity polarity)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
PWM_CONTINUOUS;
u32 val;
- if (pwm_get_polarity(pwm) = PWM_POLARITY_INVERSED)
+ if (polarity = PWM_POLARITY_INVERSED)
enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
else
enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
@@ -165,7 +168,6 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
unsigned long period, duty;
u64 clk_rate, div;
- int ret;
clk_rate = clk_get_rate(pc->clk);
@@ -182,15 +184,8 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
do_div(div, pc->data->prescaler * NSEC_PER_SEC);
duty = div;
- ret = clk_enable(pc->clk);
- if (ret)
- return ret;
-
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
- writel(0, pc->base + pc->data->regs.cntr);
-
- clk_disable(pc->clk);
return 0;
}
@@ -208,43 +203,53 @@ static int rockchip_pwm_set_polarity(struct pwm_chip *chip,
return 0;
}
-static int rockchip_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
{
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+ bool enabled = pwm_is_enabled(pwm);
int ret;
ret = clk_enable(pc->clk);
if (ret)
return ret;
- pc->data->set_enable(chip, pwm, true);
+ if (state->polarity != pwm_get_polarity(pwm) && enabled) {
+ pc->data->set_enable(chip, pwm, false, state->polarity);
+ enabled = false;
+ }
- return 0;
-}
+ ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
+ if (ret) {
+ if (enabled != pwm_is_enabled(pwm))
+ pc->data->set_enable(chip, pwm, !enabled,
+ state->polarity);
-static void rockchip_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+ goto out;
+ }
- pc->data->set_enable(chip, pwm, false);
+ if (state->enabled != enabled)
+ pc->data->set_enable(chip, pwm, state->enabled,
+ state->polarity);
+out:
clk_disable(pc->clk);
+
+ return ret;
}
static const struct pwm_ops rockchip_pwm_ops_v1 = {
.reset_state = rockchip_pwm_reset_state,
.config = rockchip_pwm_config,
- .enable = rockchip_pwm_enable,
- .disable = rockchip_pwm_disable,
+ .apply = rockchip_pwm_apply,
.owner = THIS_MODULE,
};
static const struct pwm_ops rockchip_pwm_ops_v2 = {
.reset_state = rockchip_pwm_reset_state,
.config = rockchip_pwm_config,
+ .apply = rockchip_pwm_apply,
.set_polarity = rockchip_pwm_set_polarity,
- .enable = rockchip_pwm_enable,
- .disable = rockchip_pwm_disable,
.owner = THIS_MODULE,
};
--
1.9.1
^ permalink raw reply related
* [PATCH v3 11/12] regulator: pwm: implement ->enable(), ->disable() and ->is_enabled methods
From: Boris Brezillon @ 2015-09-21 9:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1442828009-6241-1-git-send-email-boris.brezillon@free-electrons.com>
Implement the ->enable(), ->disable() and ->is_enabled methods and remove
the PWM call in ->set_voltage_sel().
This is particularly important for critical regulators tagged as always-on,
because not claiming the PWM (and its dependencies) might lead to
unpredictable behavior (like a system hang because the PWM clk is only
claimed when the PWM device is enabled).
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/regulator/pwm-regulator.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index cc549b7..9ffdbd6 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -69,12 +69,6 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
drvdata->state = selector;
- ret = pwm_enable(drvdata->pwm);
- if (ret) {
- dev_err(&rdev->dev, "Failed to enable PWM\n");
- return ret;
- }
-
return 0;
}
@@ -89,6 +83,29 @@ static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
return drvdata->duty_cycle_table[selector].uV;
}
+static int pwm_regulator_enable(struct regulator_dev *dev)
+{
+ struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+ return pwm_enable(drvdata->pwm);
+}
+
+static int pwm_regulator_disable(struct regulator_dev *dev)
+{
+ struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+ pwm_disable(drvdata->pwm);
+
+ return 0;
+}
+
+static int pwm_regulator_is_enabled(struct regulator_dev *dev)
+{
+ struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+ return pwm_is_enabled(drvdata->pwm);
+}
+
/**
* Continuous voltage call-backs
*/
@@ -144,11 +161,17 @@ static struct regulator_ops pwm_regulator_voltage_table_ops = {
.get_voltage_sel = pwm_regulator_get_voltage_sel,
.list_voltage = pwm_regulator_list_voltage,
.map_voltage = regulator_map_voltage_iterate,
+ .enable = pwm_regulator_enable,
+ .disable = pwm_regulator_disable,
+ .is_enabled = pwm_regulator_is_enabled,
};
static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
.get_voltage = pwm_regulator_get_voltage,
.set_voltage = pwm_regulator_set_voltage,
+ .enable = pwm_regulator_enable,
+ .disable = pwm_regulator_disable,
+ .is_enabled = pwm_regulator_is_enabled,
};
static struct regulator_desc pwm_regulator_desc = {
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox