Linux Power Management development
 help / color / mirror / Atom feed
* Re: [RFC PATCH 05/11] mfd: omap: control: core system control driver
From: Shilimkar, Santosh @ 2012-05-28 13:15 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: amit.kucheria, balbi, kishon, kbaidarov, J Keerthy, linux-pm,
	linux-omap, linux-arm-kernel
In-Reply-To: <20120528114225.GH3923@besouro>

On Mon, May 28, 2012 at 5:12 PM, Eduardo Valentin
<eduardo.valentin@ti.com> wrote:
> Hello,
>
> On Mon, May 28, 2012 at 03:24:01PM +0530, Shilimkar, Santosh wrote:
>> On Fri, May 25, 2012 at 1:55 PM, Eduardo Valentin
>> <eduardo.valentin@ti.com> wrote:
>> > This patch introduces a MFD core device driver for
>> > OMAP system control module.
>> >
>> > The control module allows software control of
>> > various static modes supported by the device. It is
>> > composed of two control submodules: general control
>> > module and device (padconfiguration) control
>> > module.
>> >
>> > In this patch, the children defined are for:
>> > . USB-phy pin control
>> > . Bangap temperature sensor
>> >
>> > Device driver is probed with postcore_initcall.
>> > However, as some of the APIs exposed by this driver
>> > may be needed in very early init phase, an early init
>> > class is also available: "early_omap_control".
>> >
>> > Signed-off-by: J Keerthy <j-keerthy@ti.com>
>> > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> > Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
>> > ---
>>
>> [..]
>> > diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
>> > index ad95c7a..222dbad 100644
>> > --- a/arch/arm/plat-omap/Kconfig
>> > +++ b/arch/arm/plat-omap/Kconfig
>> > @@ -5,6 +5,9 @@ menu "TI OMAP Common Features"
>> >  config ARCH_OMAP_OTG
>> >        bool
>> >
>> > +config ARCH_HAS_CONTROL_MODULE
>> > +       bool
>> > +
>> Thanks for getting rid of OMAP CONFIG here.
>
> OK. ARCH_HAS_CONTROL_MODULE is a bit too generic though..
>
>>
>> >  choice
>> >        prompt "OMAP System Type"
>> >        default ARCH_OMAP2PLUS
>> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>> > index 11e4438..25a66d8 100644
>> > --- a/drivers/mfd/Kconfig
>> > +++ b/drivers/mfd/Kconfig
>> > @@ -795,6 +795,15 @@ config MFD_WL1273_CORE
>> >          driver connects the radio-wl1273 V4L2 module and the wl1273
>> >          audio codec.
>> >
>> > +config MFD_OMAP_CONTROL
>> > +       bool "Texas Instruments OMAP System control module"
>> > +       depends on ARCH_HAS_CONTROL_MODULE
>> > +       help
>> > +         This is the core driver for system control module. This driver
>> > +         is responsible for creating the control module mfd child,
>> > +         like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic
>> > +         change for off mode.
>> > +
>> >  config MFD_OMAP_USB_HOST
>> >        bool "Support OMAP USBHS core driver"
>> >        depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
>> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
>> > index 05fa538..00f99d6 100644
>> > --- a/drivers/mfd/Makefile
>> > +++ b/drivers/mfd/Makefile
>> > @@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X)  += tps6586x.o
>> >  obj-$(CONFIG_MFD_VX855)                += vx855.o
>> >  obj-$(CONFIG_MFD_WL1273_CORE)  += wl1273-core.o
>> >  obj-$(CONFIG_MFD_CS5535)       += cs5535-mfd.o
>> > +obj-$(CONFIG_MFD_OMAP_CONTROL) += omap-control-core.o
>> >  obj-$(CONFIG_MFD_OMAP_USB_HOST)        += omap-usb-host.o
>> >  obj-$(CONFIG_MFD_PM8921_CORE)  += pm8921-core.o
>> >  obj-$(CONFIG_MFD_PM8XXX_IRQ)   += pm8xxx-irq.o
>> > diff --git a/drivers/mfd/omap-control-core.c b/drivers/mfd/omap-control-core.c
>> > new file mode 100644
>> > index 0000000..7d8d408
>> > --- /dev/null
>> > +++ b/drivers/mfd/omap-control-core.c
>> > @@ -0,0 +1,211 @@
>> > +/*
>> > + * OMAP system control module driver file
>> > + *
>> > + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
>> > + * Contacts:
>> > + * Based on original code written by:
>> > + *    J Keerthy <j-keerthy@ti.com>
>> > + *    Moiz Sonasath <m-sonasath@ti.com>
>> > + * MFD clean up and re-factoring:
>> > + *    Eduardo Valentin <eduardo.valentin@ti.com>
>> > + *
>> > + * This program is free software; you can redistribute it and/or
>> > + * modify it under the terms of the GNU General Public License
>> > + * version 2 as published by the Free Software Foundation.
>> > + *
>> > + * This program is distributed in the hope that it will be useful, but
>> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> > + * General Public License for more details.
>> > + *
>> > + */
>> > +
>> > +#include <linux/module.h>
>> > +#include <linux/export.h>
>> > +#include <linux/platform_device.h>
>> > +#include <linux/slab.h>
>> > +#include <linux/io.h>
>> > +#include <linux/err.h>
>> > +#include <linux/of_platform.h>
>> > +#include <linux/of_address.h>
>> > +#include <linux/mfd/core.h>
>> > +#include <linux/mfd/omap_control.h>
>> > +
>> > +static struct omap_control *omap_control_module;
>> > +
>> > +/**
>> > + * omap_control_readl: Read a single omap control module register.
>> > + *
>> > + * @dev: device to read from.
>> > + * @reg: register to read.
>> > + * @val: output with register value.
>> > + *
>> > + * returns 0 on success or -EINVAL in case struct device is invalid.
>> > + */
>> > +int omap_control_readl(struct device *dev, u32 reg, u32 *val)
>> > +{
>> > +       struct omap_control *omap_control = dev_get_drvdata(dev);
>> > +
>> > +       if (!omap_control)
>> > +               return -EINVAL;
>> > +
>> > +       *val = readl(omap_control->base + reg);
>> > +
>> > +       return 0;
>> > +}
>> > +EXPORT_SYMBOL_GPL(omap_control_readl);
>> > +
>> I might have missed in the last scan, but can you let
>> function return the register value.
>
> Why?
>
Because thats how typical read 1 value kind of functions
look like..

>>
>> I am guessing, you did this for error case handling. You might
>> want to stick to read API semantic and just have WARN_ON()
>> to take care of error case.
>
> Yeah, that was for error handling and to do not confuse register
> values with error values.
>
No strong opinion if you like it that way but it just appeared odd to
me from a caller perspective.

>>
>> > +/**
>> > + * omap_control_writel: Write a single omap control module register.
>> > + *
>> > + * @dev: device to read from.
>> > + * @val: value to write.
>> > + * @reg: register to write to.
>> > + *
>> > + * returns 0 on success or -EINVAL in case struct device is invalid.
>> > + */
>> > +int omap_control_writel(struct device *dev, u32 val, u32 reg)
>> > +{
>> > +       struct omap_control *omap_control = dev_get_drvdata(dev);
>> > +       unsigned long flags;
>> > +
>> > +       if (!omap_control)
>> > +               return -EINVAL;
>> > +
>> > +       spin_lock_irqsave(&omap_control->reg_lock, flags);
>> > +       writel(val, omap_control->base + reg);
>> > +       spin_unlock_irqrestore(&omap_control->reg_lock, flags);
>> > +
>> > +       return 0;
>> > +}
>> > +EXPORT_SYMBOL_GPL(omap_control_writel);
>> > +
>> > +/**
>> > + * omap_control_get: returns the control module device pinter
>> > + *
>> > + * The modules which has to use control module API's to read or write should
>> > + * call this API to get the control module device pointer.
>> > + */
>> > +struct device *omap_control_get(void)
>> > +{
>> > +       unsigned long flags;
>> > +
>> > +       if (!omap_control_module)
>> > +               return ERR_PTR(-ENODEV);
>> > +
>> > +       spin_lock_irqsave(&omap_control_module->reg_lock, flags);
>> > +       omap_control_module->use_count++;
>> > +       spin_unlock_irqrestore(&omap_control_module->reg_lock, flags);
>> > +
>> > +       return omap_control_module->dev;
>> > +}
>> > +EXPORT_SYMBOL_GPL(omap_control_get);
>> > +
>> > +/**
>> > + * omap_control_put: returns the control module device pinter
>> > + *
>> > + * The modules which has to use control module API's to read or write should
>> > + * call this API to get the control module device pointer.
>> > + */
>> > +void omap_control_put(struct device *dev)
>> > +{
>> > +       struct omap_control *omap_control = dev_get_drvdata(dev);
>> > +       unsigned long flags;
>> > +
>> > +       if (!omap_control)
>> > +               return;
>> > +
>> > +       spin_lock_irqsave(&omap_control->reg_lock, flags);
>> > +       omap_control->use_count--;
>> > +       spin_unlock_irqrestore(&omap_control_module->reg_lock, flags);
>> > +}
>> > +EXPORT_SYMBOL_GPL(omap_control_put);
>> > +
>> > +static const struct of_device_id of_omap_control_match[] = {
>> > +       { .compatible = "ti,omap3-control", },
>> > +       { .compatible = "ti,omap4-control", },
>> > +       { .compatible = "ti,omap5-control", },
>> > +       { },
>> > +};
>> > +
>> > +static int __devinit omap_control_probe(struct platform_device *pdev)
>> > +{
>> > +       struct resource *res;
>> > +       void __iomem *base;
>> > +       struct device *dev = &pdev->dev;
>> > +       struct device_node *np = dev->of_node;
>> > +       struct omap_control *omap_control;
>> > +
>> > +       omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL);
>> > +       if (!omap_control) {
>> > +               dev_err(dev, "not enough memory for omap_control\n");
>> > +               return -ENOMEM;
>> > +       }
>> > +
>> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> > +       if (!res) {
>> > +               dev_err(dev, "missing memory base resource\n");
>> > +               return -EINVAL;
>> > +       }
>> > +
>> > +       base = devm_request_and_ioremap(dev, res);
>> > +       if (!base) {
>> > +               dev_err(dev, "ioremap failed\n");
>> > +               return -EADDRNOTAVAIL;
>> > +       }
>> > +
>> > +       omap_control->base = base;
>> > +       omap_control->dev = dev;
>> > +       spin_lock_init(&omap_control->reg_lock);
>> > +
>> > +       platform_set_drvdata(pdev, omap_control);
>> > +       omap_control_module = omap_control;
>> > +
>> > +       return of_platform_populate(np, of_omap_control_match, NULL, dev);
>> > +}
>> > +
>>
>> Will the probe get called on multiple devices and race ?
>
> It depends. If we decide to have an early device for scm, then the probe will
> be called more than once. If not, then only once.
>
OK. But in either case it won't race so that's fine.

>>
>> > +static int __devexit omap_control_remove(struct platform_device *pdev)
>> > +{
>> > +       struct omap_control *omap_control = platform_get_drvdata(pdev);
>> > +
>> > +       spin_lock(&omap_control->reg_lock);
>> > +       if (omap_control->use_count > 0) {
>> > +               spin_unlock(&omap_control->reg_lock);
>> > +               dev_err(&pdev->dev, "device removed while still being used\n");
>> > +               return -EBUSY;
>> > +       }
>> > +       spin_unlock(&omap_control->reg_lock);
>> > +
>> Do you really need above lock where you are just doing the
>> register read. smp_rmb(), should be enough, I guess.
>
> It is locking the use counter not a register..
>
Yes I know. But is just read and you can do away and
hence you can avoid the lock.

Regards
Santosh

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: ehci_hcd related S3 lockup on ASUS laptops, again)
From: Rafael J. Wysocki @ 2012-05-28 20:13 UTC (permalink / raw)
  To: Andrey Rahmatullin, Steven Rostedt; +Cc: ACPI Devel Mailing List, linux-pm
In-Reply-To: <20120527211714.GC4994@belkar.wrar.name>

On Sunday, May 27, 2012, Andrey Rahmatullin wrote:
> On Sun, May 27, 2012 at 12:41:43PM -0400, Alan Stern wrote:
> > > > > > Andrey, Stephen,
> > > > > > 
> > > > > > We still have problems with this patch in https://bugzilla.kernel.org/show_bug.cgi?id=43278
> > > > > > so some more testing will be necessary, I'm afraid.
> > > > > > 
> > > > > > I will send a series of ACPI and PCI patches I have collected so far,
> > > > > > that I'd like you to test on top of kernel 3.4.0 with commit
> > > > > > 151b61284776 reverted.
> > > > > > 
> > > > > > Please let me know if suspend/wakeup work for you with these patches applied.
> > > > > I get the usual freeze on suspending with these patches.
> > > > 
> > > > I see.
> > > > 
> > > > Please try to unapply [4/4] and see if that helps.
> > > It helps.
> > 
> > Andrey, can you try out Rafael's patches 1-3 (with 151b... reverted)  
> > and see what happens if the EHCI controllers' power/wakeup sysfs
> > atributes are first set to "disabled"?
> It freezes.

Well, that means trying to work around this through changing the algorithm
of selecting the target state of a device wasn't a good idea after all.

Still, we've found some bugs in the process, so it was worth the effort.

Please attach the output of dmidecode from your machine.
Steven, please do that too.

Thanks,
Rafael

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: ehci_hcd related S3 lockup on ASUS laptops, again)
From: Andrey Rahmatullin @ 2012-05-29  7:48 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: ACPI Devel Mailing List, linux-pm, Steven Rostedt
In-Reply-To: <201205282213.01560.rjw@sisk.pl>


[-- Attachment #1.1.1: Type: text/plain, Size: 1360 bytes --]

On Mon, May 28, 2012 at 10:13:01PM +0200, Rafael J. Wysocki wrote:
> > > > > > > Andrey, Stephen,
> > > > > > > 
> > > > > > > We still have problems with this patch in https://bugzilla.kernel.org/show_bug.cgi?id=43278
> > > > > > > so some more testing will be necessary, I'm afraid.
> > > > > > > 
> > > > > > > I will send a series of ACPI and PCI patches I have collected so far,
> > > > > > > that I'd like you to test on top of kernel 3.4.0 with commit
> > > > > > > 151b61284776 reverted.
> > > > > > > 
> > > > > > > Please let me know if suspend/wakeup work for you with these patches applied.
> > > > > > I get the usual freeze on suspending with these patches.
> > > > > 
> > > > > I see.
> > > > > 
> > > > > Please try to unapply [4/4] and see if that helps.
> > > > It helps.
> > > 
> > > Andrey, can you try out Rafael's patches 1-3 (with 151b... reverted)  
> > > and see what happens if the EHCI controllers' power/wakeup sysfs
> > > atributes are first set to "disabled"?
> > It freezes.
> 
> Well, that means trying to work around this through changing the algorithm
> of selecting the target state of a device wasn't a good idea after all.
> 
> Still, we've found some bugs in the process, so it was worth the effort.
> 
> Please attach the output of dmidecode from your machine.
Attached.


-- 
WBR, wRAR

[-- Attachment #1.1.2: dmidecode-K53E.txt.gz --]
[-- Type: application/octet-stream, Size: 3902 bytes --]

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [RFC PATCH 03/11] arm: omap: device: create a device for system control module
From: Eduardo Valentin @ 2012-05-29  9:44 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: amit.kucheria, kbaidarov, kishon, balbi, linux-pm, linux-omap,
	linux-arm-kernel
In-Reply-To: <4FBF7B74.4020302@ti.com>

On Fri, May 25, 2012 at 02:30:44PM +0200, Cousson Benoit wrote:
> On 5/25/2012 10:25 AM, Eduardo Valentin wrote:
> >From: Kishon Vijay Abraham I<kishon@ti.com>
> >
> >Extracts the device data from hwmod database and create a platform device
> >using omap device build.
> >
> >The device build is done during postcore_initcall.
> 
> Do you still need that since you are supporting only DT?
> The device will be built automatically in the DT case.

In fact this is not needed for DT only probing. Dropping this one.

> 
> Regards,
> Benoit
> 
> >
> >Signed-off-by: Kishon Vijay Abraham I<kishon@ti.com>
> >Signed-off-by: Eduardo Valentin<eduardo.valentin@ti.com>
> >---
> >  arch/arm/mach-omap2/devices.c |   26 ++++++++++++++++++++++++++
> >  1 files changed, 26 insertions(+), 0 deletions(-)
> >
> >diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
> >index 152c266..9332673 100644
> >--- a/arch/arm/mach-omap2/devices.c
> >+++ b/arch/arm/mach-omap2/devices.c
> >@@ -40,6 +40,32 @@
> >  #define L3_MODULES_MAX_LEN 12
> >  #define L3_MODULES 3
> >
> >+static int omap_init_control(void)
> >+{
> >+	struct omap_hwmod		*oh;
> >+	struct platform_device		*pdev;
> >+	const char			*oh_name, *name;
> >+
> >+	oh_name = "ctrl_module_core";
> >+	name = "omap-control-core";
> >+
> >+	oh = omap_hwmod_lookup(oh_name);
> >+	if (!oh) {
> >+		pr_err("Could not lookup hwmod for %s\n", oh_name);
> >+		return PTR_ERR(oh);
> >+	}
> >+
> >+	pdev = omap_device_build(name, -1, oh, NULL, 0, NULL, 0, true);
> >+	if (IS_ERR(pdev)) {
> >+		pr_err("Could not build omap_device for %s %s\n",
> >+		       name, oh_name);
> >+		return PTR_ERR(pdev);
> >+	}
> >+
> >+	return 0;
> >+}
> >+postcore_initcall(omap_init_control);
> >+
> >  static int __init omap3_l3_init(void)
> >  {
> >  	struct omap_hwmod *oh;
> 

^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Konstantin Baydarov @ 2012-05-29  9:49 UTC (permalink / raw)
  To: Eduardo Valentin
  Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, balbi,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap
In-Reply-To: <1337934361-1606-12-git-send-email-eduardo.valentin@ti.com>

  Hi, Eduardo.

On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
> This patch add device tree entries on OMAP4 based boards
> for System Control Module (SCM).
>
> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> ---
>  arch/arm/boot/dts/omap4.dtsi |   13 +++++++++++++
>  1 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
> index 359c497..d2cb392 100644
> --- a/arch/arm/boot/dts/omap4.dtsi
> +++ b/arch/arm/boot/dts/omap4.dtsi
> @@ -272,5 +272,18 @@
>  			ti,hwmods = "mmc5";
>  			ti,needs-special-reset;
>  		};
> +
> +		ctrl_module_core: ctrl_module_core@4a002000 {
> +			compatible = "ti,omap4-control";
> +			ti,hwmods = "ctrl_module_core";
> +			bandgap {
> +				compatible = "ti,omap4460-bandgap";
> +				interrupts = <0 126 4>; /* talert */
> +				ti,tshut-gpio = <86>; /* tshut */
> +			};
I believe that CPU-specific bandgap definition should be moved to bard specific dts.

  BR,
    Konstantin Baydarov.

> +			usb {
> +				compatible = "ti,omap4-usb-phy";
> +			};
> +		};
>  	};
>  };


^ permalink raw reply

* Re: [RFC PATCH 10/11] omap4: thermal: add basic CPU thermal zone
From: Cousson, Benoit @ 2012-05-29 12:54 UTC (permalink / raw)
  To: Valentin, Eduardo
  Cc: balbi, Shilimkar, Santosh, kishon, kbaidarov, tony, paul,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap
In-Reply-To: <CAGF5oy9Dwrasv3Hr_fkGg2N5uBei4tyRbZ+ADrEZ1FR-R_Q+0w@mail.gmail.com>

On 5/28/2012 12:26 PM, Valentin, Eduardo wrote:
> Hello Santosh,
>
> On Mon, May 28, 2012 at 12:48 PM, Felipe Balbi<balbi@ti.com>  wrote:
>> Hi,
>>
>> On Mon, May 28, 2012 at 03:03:26PM +0530, Shilimkar, Santosh wrote:
>>> On Fri, May 25, 2012 at 1:56 PM, Eduardo Valentin
>>> <eduardo.valentin@ti.com>  wrote:
>>>> This patch exposes OMAP4 thermal sensor as a thermal zone
>>>> named "cpu". Only thermal creation is done here.
>>>>
>>>> TODO:
>>>>
>>>>   - Add cooling bindings
>>>>   - Add extrapolation rules
>>>>
>>>> Signed-off-by: Eduardo Valentin<eduardo.valentin@ti.com>
>>>> ---
>>>>   drivers/thermal/Kconfig         |   12 ++++++
>>>>   drivers/thermal/Makefile        |    1 +
>>>>   drivers/thermal/omap-bandgap.c  |    1 +
>>>>   drivers/thermal/omap-bandgap.h  |   12 ++++++
>>>>   drivers/thermal/omap4-thermal.c |   72 +++++++++++++++++++++++++++++++++++++++
>>>>   5 files changed, 98 insertions(+), 0 deletions(-)
>>>>   create mode 100644 drivers/thermal/omap4-thermal.c
>>>>
>>>> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>>>> index ffdd240..2e82797 100644
>>>> --- a/drivers/thermal/Kconfig
>>>> +++ b/drivers/thermal/Kconfig
>>>> @@ -39,3 +39,15 @@ config OMAP_BANDGAP
>>>>           This includes alert interrupts generation and also the TSHUT
>>>>           support.
>>>>
>>>> +config OMAP4_THERMAL
>>>> +       bool "Texas Instruments OMAP4 thermal support"
>>>> +       depends on OMAP_BANDGAP
>>>> +       depends on ARCH_OMAP4
>>>> +       help
>>>> +         If you say yes here you get thermal support for the Texas Instruments
>>>> +         OMAP4 SoC family. The current chip supported are:
>>>> +          - OMAP4460
>>>> +
>>> It's more of IP feature than OMAP specific, so something like
>>>
>>> config  HAVE_BANDGAP_THERMAL_SUPPORT
>>>
>>> and then let processor's which support enable it. That OMAP varients
>>> in AMXX etc if needed can make use of it.
>>
>> Those are just an OMAP in disguise.
>>
>>> If you agree, then rest of the driver also can be cleaned to avoid
>>> omap_* in file names and variables.
>>>
>>> Apart from this minor comment, rest of the patch looks fine to me.
>>
>> Then it will appear as a fully generic bandgap driver, which is not the
>> case. This is really a TI thing, right ?
>
> I have to agree with Felipe here. I do see your point to have a name
> which is applicable to AMxx, but having such generic naming is not
> helping either :-( as this bandgap driver is not supposed to be
> generic.
>
> I though of "ti_bandgap.*", but still seams to be misleading..

Yeah, I guess omap_bandgap is good enough. This issues is mainly due to 
the version in OMAP4 for my point of view.

Benoit

^ permalink raw reply

* Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor
From: Cousson, Benoit @ 2012-05-29 13:14 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: amit.kucheria, balbi, kishon, kbaidarov, Keerthy, linux-pm,
	linux-omap, linux-arm-kernel
In-Reply-To: <20120528111624.GC3923@besouro>

On 5/28/2012 1:16 PM, Eduardo Valentin wrote:
> Hello again,
>
> On Fri, May 25, 2012 at 05:49:44PM +0200, Cousson Benoit wrote:
>> On 5/25/2012 10:25 AM, Eduardo Valentin wrote:
>
> <big cut>
>
>>> +
>>> +static const struct omap_bandgap_data omap4460_data = {
>>> +	.has_talert = true,
>>> +	.has_tshut = true,
>>> +	.fclock_name = "bandgap_ts_fclk",
>>> +	.div_ck_name = "div_ts_ck",
>>
>> None of these clock data should be there ideally. You should ensure
>> that the proper device alias will be there using clkdev entries.
>
> In fact, it is a shame that it would be needed to have this entries there :-(
>
>>
>> Except that with DT, it will not work without the clock DT binding :-(
>>
>> I think Rob posted a latest update based on CCF... but for the
>> moment we are stuck :-(
>
> OK. But would it work for BG as well as it seams to be a special case?
>
>>
>>> +	.conv_table = omap4460_adc_to_temp,
>>> +	.sensors = {
>>> +		{
>>> +			.registers =&omap4460_mpu_temp_sensor_registers,
>>> +			.ts_data =&omap4460_mpu_temp_sensor_data,
>>> +			.domain = "cpu",
>>> +		},
>>> +	},
>>> +	.sensor_count = 1,
>>> +};
>>> +
>>> +static const struct omap_bandgap_data omap5430_data = {
>>> +	.has_talert = true,
>>> +	.has_tshut = true,
>>> +	.fclock_name = "ts_clk_div_ck",
>>> +	.div_ck_name = "ts_clk_div_ck",
>>> +	.conv_table = omap5430_adc_to_temp,
>>> +	.sensors = {
>>> +		{
>>> +			.registers =&omap5430_mpu_temp_sensor_registers,
>>> +			.ts_data =&omap5430_mpu_temp_sensor_data,
>>> +			.domain = "cpu",
>>> +		},
>>> +		{
>>> +			.registers =&omap5430_gpu_temp_sensor_registers,
>>> +			.ts_data =&omap5430_gpu_temp_sensor_data,
>>> +			.domain = "gpu",
>>> +		},
>>> +		{
>>> +			.registers =&omap5430_core_temp_sensor_registers,
>>> +			.ts_data =&omap5430_core_temp_sensor_data,
>>> +			.domain = "core",
>>> +		},
>>> +	},
>>> +	.sensor_count = 3,
>>
>> It can probably be replaced by a sizeof.
>
> ARRAY_SIZE prob, will check.

Ah, yes, that's one... I was looking for it for forgot the name :-)

>>> +};
>>> +
>>> +static const struct of_device_id of_omap_bandgap_match[] = {
>>> +	/*
>>> +	 * TODO: Add support to 4430
>>> +	 * { .compatible = "ti,omap4430-bandgap", .data = , },
>>> +	 */
>>> +	{
>>> +		.compatible = "ti,omap4460-bandgap",
>>> +		.data = (void *)&omap4460_data,
>>
>> No need to cast toward a void *.
>
> In this case, there is a need, because the omap4460_data is const but the .data field isn't. So I need to force it.
>
>>
>>> +	},
>>> +	{
>>> +		.compatible = "ti,omap5430-bandgap",
>>> +		.data = (void *)&omap5430_data,
>>> +	},
>>> +	/* Sentinel */
>>> +	{ },
>>> +};
>>> +
>>> +static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev)
>>> +{
>>> +	struct device_node *node = pdev->dev.of_node;
>>> +	const struct of_device_id *of_id;
>>> +	struct omap_bandgap *bg_ptr;
>>
>> bg_ptr is not a super name.
>
> Got a better name? Just don't want a long one to avoid code bending at 80th column...

My concern was mainly with the _ptr, it looks like a Hungarian notation. 
:-)...

Maybe bg only? Or omap_bg?

>
>>
>>> +	u32 prop;
>>> +
>>> +	/* just for the sake */
>>> +	if (!node) {
>>> +		dev_err(&pdev->dev, "no platform information available\n");
>>> +		return ERR_PTR(-EINVAL);
>>> +	}
>>
>> Not needed, just do the of_match_device here directly.
>
> Indeed...
>
>>
>>> +
>>> +	bg_ptr = devm_kzalloc(&pdev->dev, sizeof(struct omap_bandgap),
>>> +				    GFP_KERNEL);
>>> +	if (!bg_ptr) {
>>> +		dev_err(&pdev->dev, "Unable to allocate mem for driver ref\n");
>>> +		return ERR_PTR(-ENOMEM);
>>> +	}
>>> +
>>> +	of_id = of_match_device(of_omap_bandgap_match,&pdev->dev);
>>> +	if (of_id)
>>> +		bg_ptr->pdata = of_id->data;
>>
>> Nit: This is not really pdata anymore, so you should maybe remove
>> the "p" to avoid confusion.
>
> OK...
>
>>
>>> +
>>> +	if (bg_ptr->pdata->has_tshut) {
>>> +		if (of_property_read_u32(node, "ti,tshut-gpio",&prop)<   0) {
>>> +			dev_err(&pdev->dev, "missing tshut gpio in device tree\n");
>>> +			return ERR_PTR(-EINVAL);
>>> +		}
>>> +		bg_ptr->tshut_gpio = prop;
>>> +		if (!gpio_is_valid(bg_ptr->tshut_gpio)) {
>>> +			dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
>>> +				bg_ptr->tshut_gpio);
>>> +			return ERR_PTR(-EINVAL);
>>> +		}
>>> +	}
>>> +
>>> +	return bg_ptr;
>>> +}
>>> +
>>> +static
>>> +int __devinit omap_bandgap_probe(struct platform_device *pdev)
>>> +{
>>> +	struct device *cdev = pdev->dev.parent;
>>> +	struct omap_bandgap *bg_ptr;
>>> +	int clk_rate, ret = 0, i;
>>> +
>>> +	if (!cdev) {
>>> +		dev_err(&pdev->dev, "no omap control ref in our parent\n");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	bg_ptr = omap_bandgap_build(pdev);
>>> +	if (IS_ERR_OR_NULL(bg_ptr)) {
>>> +		dev_err(&pdev->dev, "failed to fetch platform data\n");
>>> +		return PTR_ERR(bg_ptr);
>>> +	}
>>> +
>>> +	if (bg_ptr->pdata->has_talert) {
>>
>> Nit2: Yeah, in fact instead of pdata, "conf" or "settings" seems to
>> be more representative of what this structure really contain.
>
> conf looks good to me.
>
>>
>>> +		ret = omap_bandgap_talert_init(bg_ptr, pdev);
>>> +		if (ret) {
>>> +			dev_err(&pdev->dev, "failed to initialize Talert IRQ\n");
>>> +			return ret;
>>> +		}
>>> +	}
>>> +
>>> +	if (bg_ptr->pdata->has_tshut) {
>>> +		ret = omap_bandgap_tshut_init(bg_ptr, pdev);
>>> +		if (ret) {
>>> +			dev_err(&pdev->dev,
>>> +				"failed to initialize system tshut IRQ\n");
>>> +			goto free_talert;
>>> +		}
>>> +	}
>>> +
>>> +	bg_ptr->fclock = clk_get(NULL, bg_ptr->pdata->fclock_name);
>>
>> That's not good to get a clock without using the local dev alias.
>> But because of lack of clock DT binding yet, I'm not sure we have
>> the choice.
>
> In fact I didn't touch the clk data on purpose and left the clock handling
> as is. On my side I didn't know how the clock struct would look like with DT,
> so, I didn't mess with it.
>
> Do you have a reference to check the work in progress for clock DT ?

Rob sent a pull request, it seems that now it is up to Mike T. :-)

http://lists-archives.com/linux-kernel/27640907-dt-clk-binding-support.html

>
>>
>>> +	ret = IS_ERR_OR_NULL(bg_ptr->fclock);
>>> +	if (ret) {
>>> +		dev_err(&pdev->dev, "failed to request fclock reference\n");
>>> +		goto free_irqs;
>>> +	}
>>> +
>>> +	bg_ptr->div_clk = clk_get(NULL,  bg_ptr->pdata->div_ck_name);
>>> +	ret = IS_ERR_OR_NULL(bg_ptr->div_clk);
>>> +	if (ret) {
>>> +		dev_err(&pdev->dev,
>>> +			"failed to request div_ts_ck clock ref\n");
>>> +		goto free_irqs;
>>> +	}
>>> +
>>> +	bg_ptr->conv_table = bg_ptr->pdata->conv_table;
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++) {
>>> +		struct temp_sensor_registers *tsr;
>>> +		u32 val;
>>> +
>>> +		tsr = bg_ptr->pdata->sensors[i].registers;
>>> +		/*
>>> +		 * check if the efuse has a non-zero value if not
>>> +		 * it is an untrimmed sample and the temperatures
>>> +		 * may not be accurate
>>> +		 */
>>> +		ret = omap_control_readl(cdev, tsr->bgap_efuse,&val);
>>> +		if (ret || !val)
>>> +			dev_info(&pdev->dev,
>>> +				 "Non-trimmed BGAP, Temp not accurate\n");
>>> +	}
>>> +
>>> +	clk_rate = clk_round_rate(bg_ptr->div_clk,
>>> +				  bg_ptr->pdata->sensors[0].ts_data->max_freq);
>>> +	if (clk_rate<   bg_ptr->pdata->sensors[0].ts_data->min_freq ||
>>> +	    clk_rate == 0xffffffff) {
>>> +		ret = -ENODEV;
>>> +		goto put_clks;
>>> +	}
>>> +
>>> +	ret = clk_set_rate(bg_ptr->div_clk, clk_rate);
>>> +	if (ret) {
>>> +		dev_err(&pdev->dev, "Cannot set clock rate\n");
>>> +		goto put_clks;
>>> +	}
>>> +
>>> +	bg_ptr->clk_rate = clk_rate;
>>> +	clk_enable(bg_ptr->fclock);
>>> +
>>> +	mutex_init(&bg_ptr->bg_mutex);
>>> +	bg_ptr->dev =&pdev->dev;
>>> +	platform_set_drvdata(pdev, bg_ptr);
>>> +
>>> +	/* 1 clk cycle */
>>
>> What does that mean exactly?
>
> That's indeed a good question. I guess by default we configure the bandgap to
> wait only 1 cycle before it goes to the next read round, if in continuous mode.

OK, so some more explanation in that comment are maybe required.

Thanks,
Benoit

>
> That should get overwritten when we have, for instance, some policy initialized
> and changing the update rate based on the temperature level that the sensor is.
>
> These decisions would go under omapXX-thermal.c, BTW. Check my reply on your
> suggestion for data structure split.
>
>>
>> Regards,
>> Benoit
>>
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++)
>>> +		configure_temp_sensor_counter(bg_ptr, i, 1);
>>> +
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++) {
>>> +		struct temp_sensor_data *ts_data;
>>> +
>>> +		ts_data = bg_ptr->pdata->sensors[i].ts_data;
>>> +
>>> +		temp_sensor_init_talert_thresholds(bg_ptr, i,
>>> +						   ts_data->t_hot,
>>> +						   ts_data->t_cold);
>>> +		temp_sensor_configure_tshut_hot(bg_ptr, i,
>>> +						ts_data->tshut_hot);
>>> +		temp_sensor_configure_tshut_cold(bg_ptr, i,
>>> +						 ts_data->tshut_cold);
>>> +	}
>>> +
>>> +	enable_continuous_mode(bg_ptr);
>>> +
>>> +	/* Set .250 seconds time as default counter */
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++)
>>> +		configure_temp_sensor_counter(bg_ptr, i,
>>> +					      bg_ptr->clk_rate / 4);
>>> +
>>> +	/* Every thing is good? Then expose the sensors */
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++) {
>>> +		char *domain;
>>> +
>>> +		domain = bg_ptr->pdata->sensors[i].domain;
>>> +		if (bg_ptr->pdata->expose_sensor)
>>> +			bg_ptr->pdata->expose_sensor(bg_ptr, i, domain);
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +put_clks:
>>> +	clk_disable(bg_ptr->fclock);
>>> +	clk_put(bg_ptr->fclock);
>>> +	clk_put(bg_ptr->div_clk);
>>> +free_irqs:
>>> +	free_irq(gpio_to_irq(bg_ptr->tshut_gpio), NULL);
>>> +	gpio_free(bg_ptr->tshut_gpio);
>>> +free_talert:
>>> +	free_irq(bg_ptr->irq, bg_ptr);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static
>>> +int __devexit omap_bandgap_remove(struct platform_device *pdev)
>>> +{
>>> +	struct omap_bandgap *bg_ptr = platform_get_drvdata(pdev);
>>> +
>>> +	clk_disable(bg_ptr->fclock);
>>> +	clk_put(bg_ptr->fclock);
>>> +	clk_put(bg_ptr->div_clk);
>>> +	free_irq(bg_ptr->irq, bg_ptr);
>>> +	free_irq(gpio_to_irq(bg_ptr->tshut_gpio), NULL);
>>> +	gpio_free(bg_ptr->tshut_gpio);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +#ifdef CONFIG_PM
>>> +static int omap_bandgap_save_ctxt(struct omap_bandgap *bg_ptr)
>>> +{
>>> +	struct device *cdev = bg_ptr->dev->parent;
>>> +	int err = 0;
>>> +	int i;
>>> +
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++) {
>>> +		struct temp_sensor_registers *tsr;
>>> +		struct temp_sensor_regval *rval;
>>> +
>>> +		rval = bg_ptr->pdata->sensors[i].regval;
>>> +		tsr = bg_ptr->pdata->sensors[i].registers;
>>> +
>>> +		err = omap_control_readl(cdev, tsr->bgap_mode_ctrl,
>>> +					&rval->bg_mode_ctrl);
>>> +		err |= omap_control_readl(cdev,	tsr->bgap_mask_ctrl,
>>> +					&rval->bg_ctrl);
>>> +		err |= omap_control_readl(cdev,	tsr->bgap_counter,
>>> +					&rval->bg_counter);
>>> +		err |= omap_control_readl(cdev, tsr->bgap_threshold,
>>> +					&rval->bg_threshold);
>>> +		err |= omap_control_readl(cdev, tsr->tshut_threshold,
>>> +					&rval->tshut_threshold);
>>> +
>>> +		if (err)
>>> +			dev_err(bg_ptr->dev, "could not save sensor %d\n", i);
>>> +	}
>>> +
>>> +	return err ? -EIO : 0;
>>> +}
>>> +
>>> +static int
>>> +omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id)
>>> +{
>>> +	struct device *cdev = bg_ptr->dev->parent;
>>> +	struct temp_sensor_registers *tsr;
>>> +	u32 temp = 0, counter = 1000;
>>> +	int err;
>>> +
>>> +	tsr = bg_ptr->pdata->sensors[id].registers;
>>> +	/* Select single conversion mode */
>>> +	err = omap_control_readl(cdev, tsr->bgap_mode_ctrl,&temp);
>>> +	temp&= ~(1<<   __ffs(tsr->mode_ctrl_mask));
>>> +	omap_control_writel(cdev, temp, tsr->bgap_mode_ctrl);
>>> +
>>> +	/* Start of Conversion = 1 */
>>> +	err |= omap_control_readl(cdev, tsr->temp_sensor_ctrl,&temp);
>>> +	temp |= 1<<   __ffs(tsr->bgap_soc_mask);
>>> +	omap_control_writel(cdev, temp, tsr->temp_sensor_ctrl);
>>> +	/* Wait until DTEMP is updated */
>>> +	err |= omap_control_readl(cdev, tsr->temp_sensor_ctrl,&temp);
>>> +	temp&= (tsr->bgap_dtemp_mask);
>>> +	while ((temp == 0)&&   --counter) {
>>> +		err |= omap_control_readl(cdev, tsr->temp_sensor_ctrl,&temp);
>>> +		temp&= (tsr->bgap_dtemp_mask);
>>> +	}
>>> +	/* Start of Conversion = 0 */
>>> +	err |= omap_control_readl(cdev, tsr->temp_sensor_ctrl,&temp);
>>> +	temp&= ~(1<<   __ffs(tsr->bgap_soc_mask));
>>> +	err |= omap_control_writel(cdev, temp, tsr->temp_sensor_ctrl);
>>> +
>>> +	return err ? -EIO : 0;
>>> +}
>>> +
>>> +static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr)
>>> +{
>>> +	struct device *cdev = bg_ptr->dev->parent;
>>> +	int i, err = 0;
>>> +	u32 temp = 0;
>>> +
>>> +	for (i = 0; i<   bg_ptr->pdata->sensor_count; i++) {
>>> +		struct temp_sensor_registers *tsr;
>>> +		struct temp_sensor_regval *rval;
>>> +		u32 val;
>>> +
>>> +		rval = bg_ptr->pdata->sensors[i].regval;
>>> +		tsr = bg_ptr->pdata->sensors[i].registers;
>>> +
>>> +		err = omap_control_readl(cdev, tsr->bgap_counter,&val);
>>> +		if (val == 0) {
>>> +			err |= omap_control_writel(cdev, rval->bg_threshold,
>>> +						   tsr->bgap_threshold);
>>> +			err |= omap_control_writel(cdev, rval->tshut_threshold,
>>> +						   tsr->tshut_threshold);
>>> +			/* Force immediate temperature measurement and update
>>> +			 * of the DTEMP field
>>> +			 */
>>> +			omap_bandgap_force_single_read(bg_ptr, i);
>>> +			err |= omap_control_writel(cdev, rval->bg_counter,
>>> +						   tsr->bgap_counter);
>>> +			err |= omap_control_writel(cdev, rval->bg_mode_ctrl,
>>> +						   tsr->bgap_mode_ctrl);
>>> +			err |= omap_control_writel(cdev, rval->bg_ctrl,
>>> +						   tsr->bgap_mask_ctrl);
>>> +		} else {
>>> +			err |= omap_control_readl(cdev, tsr->temp_sensor_ctrl,
>>> +						&temp);
>>> +			temp&= (tsr->bgap_dtemp_mask);
>>> +			if (temp == 0) {
>>> +				omap_bandgap_force_single_read(bg_ptr, i);
>>> +				err |= omap_control_readl(cdev,
>>> +							  tsr->bgap_mask_ctrl,
>>> +							&temp);
>>> +				temp |= 1<<   __ffs(tsr->mode_ctrl_mask);
>>> +				err |= omap_control_writel(cdev, temp,
>>> +							   tsr->bgap_mask_ctrl);
>>> +			}
>>> +		}
>>> +		if (err)
>>> +			dev_err(bg_ptr->dev, "could not save sensor %d\n", i);
>>> +	}
>>> +
>>> +	return err ? -EIO : 0;
>>> +}
>>> +
>>> +static int omap_bandgap_suspend(struct device *dev)
>>> +{
>>> +	struct omap_bandgap *bg_ptr = dev_get_drvdata(dev);
>>> +	int err;
>>> +
>>> +	err = omap_bandgap_save_ctxt(bg_ptr);
>>> +	clk_disable(bg_ptr->fclock);
>>> +
>>> +	return err;
>>> +}
>>> +
>>> +static int omap_bandgap_resume(struct device *dev)
>>> +{
>>> +	struct omap_bandgap *bg_ptr = dev_get_drvdata(dev);
>>> +
>>> +	clk_enable(bg_ptr->fclock);
>>> +
>>> +	return omap_bandgap_restore_ctxt(bg_ptr);
>>> +}
>>> +static const struct dev_pm_ops omap_bandgap_dev_pm_ops = {
>>> +	SET_SYSTEM_SLEEP_PM_OPS(omap_bandgap_suspend,
>>> +				omap_bandgap_resume)
>>> +};
>>> +
>>> +#define DEV_PM_OPS	(&omap_bandgap_dev_pm_ops)
>>> +#else
>>> +#define DEV_PM_OPS	NULL
>>> +#endif
>>> +
>>> +static struct platform_driver omap_bandgap_sensor_driver = {
>>> +	.probe = omap_bandgap_probe,
>>> +	.remove = omap_bandgap_remove,
>>> +	.driver = {
>>> +			.name = "omap-bandgap",
>>> +			.pm = DEV_PM_OPS,
>>> +			.of_match_table	= of_omap_bandgap_match,
>>> +	},
>>> +};
>>> +
>>> +module_platform_driver(omap_bandgap_sensor_driver);
>>> +early_platform_init("early_omap_temperature",&omap_bandgap_sensor_driver);
>>> +
>>> +MODULE_DESCRIPTION("OMAP4+ bandgap temperature sensor driver");
>>> +MODULE_LICENSE("GPL v2");
>>> +MODULE_ALIAS("platform:omap-bandgap");
>>> +MODULE_AUTHOR("Texas Instrument Inc.");
>>> diff --git a/drivers/thermal/omap-bandgap.h b/drivers/thermal/omap-bandgap.h
>>> new file mode 100644
>>> index 0000000..12e0d6b
>>> --- /dev/null
>>> +++ b/drivers/thermal/omap-bandgap.h
>>> @@ -0,0 +1,63 @@
>>> +/*
>>> + * OMAP4 Bandgap temperature sensor driver
>>> + *
>>> + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
>>> + * Contact:
>>> + *   Eduardo Valentin<eduardo.valentin@ti.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * version 2 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> + * General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program; if not, write to the Free Software
>>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
>>> + * 02110-1301 USA
>>> + *
>>> + */
>>> +#ifndef __OMAP_BANDGAP_H
>>> +#define __OMAP_BANDGAP_H
>>> +
>>> +struct omap_bandgap_data;
>>> +
>>> +/**
>>> + * struct omap_bandgap - bandgap device structure
>>> + * @dev: device pointer
>>> + * @pdata: platform data with sensor data
>>> + * @fclock: pointer to functional clock of temperature sensor
>>> + * @div_clk: pointer to parent clock of temperature sensor fclk
>>> + * @conv_table: Pointer to adc to temperature conversion table
>>> + * @bg_mutex: Mutex for sysfs, irq and PM
>>> + * @irq: MPU Irq number for thermal alert
>>> + * @tshut_gpio: GPIO where Tshut signal is routed
>>> + * @clk_rate: Holds current clock rate
>>> + */
>>> +struct omap_bandgap {
>>> +	struct device			*dev;
>>> +	const struct omap_bandgap_data	*pdata;
>>> +	struct clk			*fclock;
>>> +	struct clk			*div_clk;
>>> +	const int			*conv_table;
>>> +	struct mutex			bg_mutex; /* Mutex for irq and PM */
>>> +	int				irq;
>>> +	int				tshut_gpio;
>>> +	u32				clk_rate;
>>> +};
>>> +
>>> +int omap_bandgap_read_thot(struct omap_bandgap *bg_ptr, int id, int *thot);
>>> +int omap_bandgap_write_thot(struct omap_bandgap *bg_ptr, int id, int val);
>>> +int omap_bandgap_read_tcold(struct omap_bandgap *bg_ptr, int id, int *tcold);
>>> +int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val);
>>> +int omap_bandgap_read_update_interval(struct omap_bandgap *bg_ptr, int id,
>>> +				      int *interval);
>>> +int omap_bandgap_write_update_interval(struct omap_bandgap *bg_ptr, int id,
>>> +				       u32 interval);
>>> +int omap_bandgap_read_temperature(struct omap_bandgap *bg_ptr, int id,
>>> +				  int *temperature);
>>> +
>>> +#endif
>>
>
> ---
> Eduardo

^ permalink raw reply

* Re: [RFC PATCH 05/11] mfd: omap: control: core system control driver
From: Cousson, Benoit @ 2012-05-29 13:25 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: amit.kucheria, balbi, kishon, kbaidarov, J Keerthy, linux-pm,
	linux-omap, linux-arm-kernel
In-Reply-To: <20120528113502.GG3923@besouro>

On 5/28/2012 1:35 PM, Eduardo Valentin wrote:
> Hello,
>
> On Fri, May 25, 2012 at 02:52:08PM +0200, Cousson Benoit wrote:
>> On 5/25/2012 10:25 AM, Eduardo Valentin wrote:
>>> This patch introduces a MFD core device driver for
>>> OMAP system control module.
>>>
>>> The control module allows software control of
>>> various static modes supported by the device. It is
>>> composed of two control submodules: general control
>>> module and device (padconfiguration) control
>>> module.
>>>
>>> In this patch, the children defined are for:
>>> . USB-phy pin control
>>> . Bangap temperature sensor
>>>
>>> Device driver is probed with postcore_initcall.
>>> However, as some of the APIs exposed by this driver
>>> may be needed in very early init phase, an early init
>>> class is also available: "early_omap_control".
>>>
>>> Signed-off-by: J Keerthy<j-keerthy@ti.com>
>>> Signed-off-by: Kishon Vijay Abraham I<kishon@ti.com>
>>> Signed-off-by: Eduardo Valentin<eduardo.valentin@ti.com>
>>> ---
>>>   .../devicetree/bindings/mfd/omap_control.txt       |   44 ++++
>>>   arch/arm/mach-omap2/Kconfig                        |    1 +
>>>   arch/arm/plat-omap/Kconfig                         |    3 +
>>>   drivers/mfd/Kconfig                                |    9 +
>>>   drivers/mfd/Makefile                               |    1 +
>>>   drivers/mfd/omap-control-core.c                    |  211 ++++++++++++++++++++
>>>   include/linux/mfd/omap_control.h                   |   69 +++++++
>>>   7 files changed, 338 insertions(+), 0 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/mfd/omap_control.txt
>>>   create mode 100644 drivers/mfd/omap-control-core.c
>>>   create mode 100644 include/linux/mfd/omap_control.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/omap_control.txt b/Documentation/devicetree/bindings/mfd/omap_control.txt
>>> new file mode 100644
>>> index 0000000..46d5e7e
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mfd/omap_control.txt
>>> @@ -0,0 +1,44 @@
>>> +* Texas Instrument OMAP System Control Module (SCM) bindings
>>> +
>>> +The control module allows software control of various static modes supported by
>>> +the device. The control module controls the settings of various device  modules
>>> +through register configuration and internal signals. It also controls  the  pad
>>> +configuration, pin functional multiplexing, and the routing of internal signals
>>> +(such as PRCM  signals or DMA requests)  to output pins configured for hardware
>>> +observability.
>>> +
>>> +Required properties:
>>> +- compatible : Should be:
>>> +  - "ti,omap3-control" for OMAP3 support
>>> +  - "ti,omap4-control" for OMAP4 support
>>> +  - "ti,omap5-control" for OMAP5 support
>>> +
>>> +OMAP specific properties:
>>> +- ti,hwmods: Name of the hwmod associated to the control module:
>>> +  Should be "ctrl_module_core";
>>> +
>>> +Sub-nodes:
>>> +- bandgap : contains the bandgap node
>>> +
>>> +  The bindings details of individual bandgap device can be found in:
>>> +  Documentation/devicetree/bindings/thermal/omap_bandgap.txt
>>> +
>>> +- usb : contains the usb phy pin control node
>>> +
>>> +  The only required property for this child is:
>>> +    - compatible = "ti,omap4-control-usb";
>>> +
>>> +Examples:
>>> +
>>> +ctrl_module_core: ctrl_module_core@4a002000 {
>>> +	compatible = "ti,omap4-control";
>>> +	ti,hwmods = "ctrl_module_core";
>>> +	bandgap {
>>> +		compatible = "ti,omap4460-bandgap";
>>> +		interrupts =<0 126 4>; /* talert */
>>> +		ti,tshut-gpio =<86>; /* tshut */
>>> +	};
>>> +	usb {
>>> +		compatible = "ti,omap4-usb-phy";
>>> +	};
>>> +};
>>> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
>>> index a2b946d..7dfe5e1 100644
>>> --- a/arch/arm/mach-omap2/Kconfig
>>> +++ b/arch/arm/mach-omap2/Kconfig
>>> @@ -52,6 +52,7 @@ config ARCH_OMAP4
>>>   	select PL310_ERRATA_727915
>>>   	select ARM_ERRATA_720789
>>>   	select ARCH_HAS_OPP
>>> +	select ARCH_HAS_CONTROL_MODULE
>>>   	select PM_OPP if PM
>>>   	select USB_ARCH_HAS_EHCI if USB_SUPPORT
>>>   	select ARM_CPU_SUSPEND if PM
>>> diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
>>> index ad95c7a..222dbad 100644
>>> --- a/arch/arm/plat-omap/Kconfig
>>> +++ b/arch/arm/plat-omap/Kconfig
>>> @@ -5,6 +5,9 @@ menu "TI OMAP Common Features"
>>>   config ARCH_OMAP_OTG
>>>   	bool
>>>
>>> +config ARCH_HAS_CONTROL_MODULE
>>> +	bool
>>> +
>>>   choice
>>>   	prompt "OMAP System Type"
>>>   	default ARCH_OMAP2PLUS
>>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>>> index 11e4438..25a66d8 100644
>>> --- a/drivers/mfd/Kconfig
>>> +++ b/drivers/mfd/Kconfig
>>> @@ -795,6 +795,15 @@ config MFD_WL1273_CORE
>>>   	  driver connects the radio-wl1273 V4L2 module and the wl1273
>>>   	  audio codec.
>>>
>>> +config MFD_OMAP_CONTROL
>>> +	bool "Texas Instruments OMAP System control module"
>>> +	depends on ARCH_HAS_CONTROL_MODULE
>>> +	help
>>> +	  This is the core driver for system control module. This driver
>>> +	  is responsible for creating the control module mfd child,
>>> +	  like USB-pin control, pin muxing, MMC-pbias and DDR IO dynamic
>>> +	  change for off mode.
>>> +
>>>   config MFD_OMAP_USB_HOST
>>>   	bool "Support OMAP USBHS core driver"
>>>   	depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
>>> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
>>> index 05fa538..00f99d6 100644
>>> --- a/drivers/mfd/Makefile
>>> +++ b/drivers/mfd/Makefile
>>> @@ -106,6 +106,7 @@ obj-$(CONFIG_MFD_TPS6586X)	+= tps6586x.o
>>>   obj-$(CONFIG_MFD_VX855)		+= vx855.o
>>>   obj-$(CONFIG_MFD_WL1273_CORE)	+= wl1273-core.o
>>>   obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
>>> +obj-$(CONFIG_MFD_OMAP_CONTROL)	+= omap-control-core.o
>>>   obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o
>>>   obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
>>>   obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
>>> diff --git a/drivers/mfd/omap-control-core.c b/drivers/mfd/omap-control-core.c
>>> new file mode 100644
>>> index 0000000..7d8d408
>>> --- /dev/null
>>> +++ b/drivers/mfd/omap-control-core.c
>>> @@ -0,0 +1,211 @@
>>> +/*
>>> + * OMAP system control module driver file
>>> + *
>>> + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
>>> + * Contacts:
>>> + * Based on original code written by:
>>> + *    J Keerthy<j-keerthy@ti.com>
>>> + *    Moiz Sonasath<m-sonasath@ti.com>
>>> + * MFD clean up and re-factoring:
>>> + *    Eduardo Valentin<eduardo.valentin@ti.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * version 2 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> + * General Public License for more details.
>>> + *
>>> + */
>>> +
>>> +#include<linux/module.h>
>>> +#include<linux/export.h>
>>> +#include<linux/platform_device.h>
>>> +#include<linux/slab.h>
>>> +#include<linux/io.h>
>>> +#include<linux/err.h>
>>> +#include<linux/of_platform.h>
>>> +#include<linux/of_address.h>
>>> +#include<linux/mfd/core.h>
>>> +#include<linux/mfd/omap_control.h>
>>> +
>>> +static struct omap_control *omap_control_module;
>>
>> Mmm, we can have up to 4 control module instances in OMAP4.
>>
>> Well, I'm not sure it worth considering them as separate devices. Is
>> that your plan as well?
>
> At least for now I was focusing on the ctrl_module_core ...

OK, that's a good start already :-)

>> But since they all have different base address, it will be trick to
>> handle them with only a single entry.
>
> Indeed. We can always add the support latter on.
>
> I am not sure what would be the best way to handle those instances though,
> and how they are going to expose APIs. Would need to have an instance bound
> to API set?

We should not go to that path I guess. We should have an API at children 
level independent of the underlying control module partitioning.

Regards,
Benoit

>>> +
>>> +/**
>>> + * omap_control_readl: Read a single omap control module register.
>>> + *
>>> + * @dev: device to read from.
>>> + * @reg: register to read.
>>> + * @val: output with register value.
>>> + *
>>> + * returns 0 on success or -EINVAL in case struct device is invalid.
>>> + */
>>> +int omap_control_readl(struct device *dev, u32 reg, u32 *val)
>>> +{
>>> +	struct omap_control *omap_control = dev_get_drvdata(dev);
>>> +
>>> +	if (!omap_control)
>>> +		return -EINVAL;
>>> +
>>> +	*val = readl(omap_control->base + reg);
>>> +
>>> +	return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(omap_control_readl);
>>> +
>>> +/**
>>> + * omap_control_writel: Write a single omap control module register.
>>> + *
>>> + * @dev: device to read from.
>>> + * @val: value to write.
>>> + * @reg: register to write to.
>>> + *
>>> + * returns 0 on success or -EINVAL in case struct device is invalid.
>>> + */
>>> +int omap_control_writel(struct device *dev, u32 val, u32 reg)
>>> +{
>>> +	struct omap_control *omap_control = dev_get_drvdata(dev);
>>> +	unsigned long flags;
>>> +
>>> +	if (!omap_control)
>>> +		return -EINVAL;
>>> +
>>> +	spin_lock_irqsave(&omap_control->reg_lock, flags);
>>> +	writel(val, omap_control->base + reg);
>>> +	spin_unlock_irqrestore(&omap_control->reg_lock, flags);
>>> +
>>> +	return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(omap_control_writel);
>>> +
>>> +/**
>>> + * omap_control_get: returns the control module device pinter
>>
>> typo
>
> K
>
>>
>>> + *
>>> + * The modules which has to use control module API's to read or write should
>>> + * call this API to get the control module device pointer.
>>> + */
>>> +struct device *omap_control_get(void)
>>> +{
>>> +	unsigned long flags;
>>> +
>>> +	if (!omap_control_module)
>>> +		return ERR_PTR(-ENODEV);
>>> +
>>> +	spin_lock_irqsave(&omap_control_module->reg_lock, flags);
>>> +	omap_control_module->use_count++;
>>> +	spin_unlock_irqrestore(&omap_control_module->reg_lock, flags);
>>
>> Don't we do have some better way to increment atomically a variable
>> in Linux.
>
> Yeah we have, atomic API. In general I think the SCM/bangap/phy APIs
> need to be revisited WRT locking, in general.
>
>>
>>> +
>>> +	return omap_control_module->dev;
>>> +}
>>> +EXPORT_SYMBOL_GPL(omap_control_get);
>>> +
>>> +/**
>>> + * omap_control_put: returns the control module device pinter
>>> + *
>>> + * The modules which has to use control module API's to read or write should
>>> + * call this API to get the control module device pointer.
>>> + */
>>> +void omap_control_put(struct device *dev)
>>> +{
>>> +	struct omap_control *omap_control = dev_get_drvdata(dev);
>>> +	unsigned long flags;
>>> +
>>> +	if (!omap_control)
>>> +		return;
>>> +
>>> +	spin_lock_irqsave(&omap_control->reg_lock, flags);
>>> +	omap_control->use_count--;
>>> +	spin_unlock_irqrestore(&omap_control_module->reg_lock, flags);
>>> +}
>>> +EXPORT_SYMBOL_GPL(omap_control_put);
>>> +
>>> +static const struct of_device_id of_omap_control_match[] = {
>>> +	{ .compatible = "ti,omap3-control", },
>>> +	{ .compatible = "ti,omap4-control", },
>>> +	{ .compatible = "ti,omap5-control", },
>>> +	{ },
>>> +};
>>> +
>>> +static int __devinit omap_control_probe(struct platform_device *pdev)
>>> +{
>>> +	struct resource *res;
>>> +	void __iomem *base;
>>> +	struct device *dev =&pdev->dev;
>>> +	struct device_node *np = dev->of_node;
>>> +	struct omap_control *omap_control;
>>
>> Maybe omap_control_data instead? At least if this is drvdata only.
>> If this is supposed to be the *handle* to the control module
>> instance, it should be fine.
>
> That's suppose to be the phandle :-)
>
>>
>>> +
>>> +	omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL);
>>> +	if (!omap_control) {
>>> +		dev_err(dev, "not enough memory for omap_control\n");
>>> +		return -ENOMEM;
>>> +	}
>>> +
>>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +	if (!res) {
>>> +		dev_err(dev, "missing memory base resource\n");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	base = devm_request_and_ioremap(dev, res);
>>> +	if (!base) {
>>> +		dev_err(dev, "ioremap failed\n");
>>> +		return -EADDRNOTAVAIL;
>>> +	}
>>> +
>>> +	omap_control->base = base;
>>> +	omap_control->dev = dev;
>>> +	spin_lock_init(&omap_control->reg_lock);
>>> +
>>> +	platform_set_drvdata(pdev, omap_control);
>>> +	omap_control_module = omap_control;
>>> +
>>> +	return of_platform_populate(np, of_omap_control_match, NULL, dev);
>>> +}
>>> +
>>> +static int __devexit omap_control_remove(struct platform_device *pdev)
>>> +{
>>> +	struct omap_control *omap_control = platform_get_drvdata(pdev);
>>> +
>>> +	spin_lock(&omap_control->reg_lock);
>>> +	if (omap_control->use_count>   0) {
>>> +		spin_unlock(&omap_control->reg_lock);
>>> +		dev_err(&pdev->dev, "device removed while still being used\n");
>>> +		return -EBUSY;
>>> +	}
>>> +	spin_unlock(&omap_control->reg_lock);
>>> +
>>> +	iounmap(omap_control->base);
>>> +	platform_set_drvdata(pdev, NULL);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static struct platform_driver omap_control_driver = {
>>> +	.probe			= omap_control_probe,
>>> +	.remove			= __devexit_p(omap_control_remove),
>>> +	.driver = {
>>> +		.name		= "omap-control-core",
>>> +		.owner		= THIS_MODULE,
>>> +		.of_match_table	= of_omap_control_match,
>>> +	},
>>> +};
>>> +
>>> +static int __init omap_control_init(void)
>>> +{
>>> +	return platform_driver_register(&omap_control_driver);
>>> +}
>>> +postcore_initcall_sync(omap_control_init);
>>> +
>>> +static void __exit omap_control_exit(void)
>>> +{
>>> +	platform_driver_unregister(&omap_control_driver);
>>> +}
>>> +module_exit(omap_control_exit);
>>> +early_platform_init("early_omap_control",&omap_control_driver);
>>> +
>>> +MODULE_DESCRIPTION("OMAP system control module driver");
>>> +MODULE_LICENSE("GPL v2");
>>> +MODULE_ALIAS("platform:omap-control-core");
>>> +MODULE_AUTHOR("Texas Instruments Inc.");
>>> diff --git a/include/linux/mfd/omap_control.h b/include/linux/mfd/omap_control.h
>>> new file mode 100644
>>> index 0000000..7a33eda
>>> --- /dev/null
>>> +++ b/include/linux/mfd/omap_control.h
>>> @@ -0,0 +1,69 @@
>>> +/*
>>> + * OMAP system control module header file
>>> + *
>>> + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
>>> + * Contact:
>>> + *   J Keerthy<j-keerthy@ti.com>
>>> + *   Moiz Sonasath<m-sonasath@ti.com>
>>> + *   Abraham, Kishon Vijay<kishon@ti.com>
>>> + *   Eduardo Valentin<eduardo.valentin@ti.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * version 2 as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> + * General Public License for more details.
>>> + *
>>> + */
>>> +
>>> +#ifndef __DRIVERS_OMAP_CONTROL_H
>>> +#define __DRIVERS_OMAP_CONTROL_H
>>> +
>>> +#include<linux/err.h>
>>> +
>>> +/**
>>> + * struct system control module - scm device structure
>>> + * @dev: device pointer
>>> + * @base: Base of the temp I/O
>>> + * @reg_lock: protect omap_control structure
>>> + * @use_count: track API users
>>> + */
>>> +struct omap_control {
>>> +	struct device		*dev;
>>
>> Do you really need the dev?
>> You API is device based and not omap_control based, so it should not
>> be needed.
>>
>> I guess we should be consistent here. We can store the devices and
>> used a device based API or store the omap_control and thus expose a
>> omap_control API.
>
> Yeah, this API structure is left over of the previous driver.
>
> The omap_control_get returns the SCM device reference
> and the users of SCM use it as parameter for the SCM APIs.
>
> We need to have in mind that, for SCM, the users are:
> a. Its children (USB phy, BG, etc)
> b. Non children users (mach code)
>
> The refcounting and the locking needs to take care of both I'd say.
> The struct dev was just a way to pass the SCM phandle.
>
>>
>> Regards,
>> Benoit

^ permalink raw reply

* Re: [RFC PATCH 05/11] mfd: omap: control: core system control driver
From: Cousson, Benoit @ 2012-05-29 13:31 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: amit.kucheria, balbi, kishon, kbaidarov, J Keerthy, linux-pm,
	linux-omap, linux-arm-kernel
In-Reply-To: <CAMQu2gzmPqiq5Aj8Fu6Jctdzkzeq6nXVCJcVvXHn4DRB3ZqNhw@mail.gmail.com>

On 5/28/2012 3:15 PM, Shilimkar, Santosh wrote:
> On Mon, May 28, 2012 at 5:12 PM, Eduardo Valentin

[...]

>>>> +/**
>>>> + * omap_control_readl: Read a single omap control module register.
>>>> + *
>>>> + * @dev: device to read from.
>>>> + * @reg: register to read.
>>>> + * @val: output with register value.
>>>> + *
>>>> + * returns 0 on success or -EINVAL in case struct device is invalid.
>>>> + */
>>>> +int omap_control_readl(struct device *dev, u32 reg, u32 *val)
>>>> +{
>>>> +       struct omap_control *omap_control = dev_get_drvdata(dev);
>>>> +
>>>> +       if (!omap_control)
>>>> +               return -EINVAL;
>>>> +
>>>> +       *val = readl(omap_control->base + reg);
>>>> +
>>>> +       return 0;
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(omap_control_readl);
>>>> +
>>> I might have missed in the last scan, but can you let
>>> function return the register value.
>>
>> Why?
>>
> Because thats how typical read 1 value kind of functions
> look like..

Yeah, I tend to agree with Santosh here as well. I'm expecting such API 
to return the value.
Moreover the error handling in that case is really an exception and thus 
a WARM is enough since it should never ever happen except if there is a 
bug during the probe. And in that case, it should already fail at probe 
time.

>>> I am guessing, you did this for error case handling. You might
>>> want to stick to read API semantic and just have WARN_ON()
>>> to take care of error case.
>>
>> Yeah, that was for error handling and to do not confuse register
>> values with error values.
>>
> No strong opinion if you like it that way but it just appeared odd to
> me from a caller perspective.

Yep, I do agree.

Benoit

^ permalink raw reply

* Re: [RFC PATCH 03/11] arm: omap: device: create a device for system control module
From: Konstantin Baydarov @ 2012-05-29 13:39 UTC (permalink / raw)
  To: Eduardo Valentin
  Cc: b-cousson, kishon, santosh.shilimkar, tony, paul, balbi,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap, Konstantin Baydarov
In-Reply-To: <1337934361-1606-4-git-send-email-eduardo.valentin@ti.com>

  Hi.

On 05/25/2012 12:25 PM, Eduardo Valentin wrote:
> From: Kishon Vijay Abraham I <kishon@ti.com>
>
> Extracts the device data from hwmod database and create a platform device
> using omap device build.
>
> The device build is done during postcore_initcall.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
> ---
>  arch/arm/mach-omap2/devices.c |   26 ++++++++++++++++++++++++++
>  1 files changed, 26 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
> index 152c266..9332673 100644
> --- a/arch/arm/mach-omap2/devices.c
> +++ b/arch/arm/mach-omap2/devices.c
> @@ -40,6 +40,32 @@
>  #define L3_MODULES_MAX_LEN 12
>  #define L3_MODULES 3
>  
> +static int omap_init_control(void)
> +{
> +	struct omap_hwmod		*oh;
> +	struct platform_device		*pdev;
> +	const char			*oh_name, *name;
> +
> +	oh_name = "ctrl_module_core";
> +	name = "omap-control-core";
> +
> +	oh = omap_hwmod_lookup(oh_name);
> +	if (!oh) {
> +		pr_err("Could not lookup hwmod for %s\n", oh_name);
> +		return PTR_ERR(oh);
> +	}
> +
> +	pdev = omap_device_build(name, -1, oh, NULL, 0, NULL, 0, true);
I noticed that control module omap device is created and configured according to following idle flags:
static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = {
    .rev_offs    = 0x0000,
    .sysc_offs    = 0x0010,
    .sysc_flags    = SYSC_HAS_SIDLEMODE,
    .idlemodes    = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
               SIDLE_SMART_WKUP),
    .sysc_fields    = &omap_hwmod_sysc_type2,
};

IIUC, ".idlemodes    = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | SIDLE_SMART_WKUP)" means that CONTROL_GEN_CORE idlemode will be set to
"0x2,0x3: Clock is automatically gated when there is no access to the Control Module through L4-interconnect". See CONTROL_GEN_CORE_SYSCONFIG register.
So IIUC theoretically CONTROL_GEN_CORE module clock can be automatically gated. Recalling that CONTROL_GEN_CORE module has an THERMAL_ALERT interrupt that is used by the bandgap driver, I'm wondering if the THERMAL_ALERT interrupt will be fired when CONTROL_GEN_CORE module clock is gated?
Probably bandgap driver should set CONTROL_GEN_CORE idle mode to SIDLE_NO, to prevent loosing THERMAL_ALERT interrupt?

  BR,
    Konstantin Baydarov.

> +	if (IS_ERR(pdev)) {
> +		pr_err("Could not build omap_device for %s %s\n",
> +		       name, oh_name);
> +		return PTR_ERR(pdev);
> +	}
> +
> +	return 0;
> +}
> +postcore_initcall(omap_init_control);
> +
>  static int __init omap3_l3_init(void)
>  {
>  	struct omap_hwmod *oh;


^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again)
From: Alan Stern @ 2012-05-29 14:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Oleksij Rempel (fishor), Dâniel Fraga, Andrey Rahmatullin,
	Steven Rostedt, linux-pm, ACPI Devel Mailing List
In-Reply-To: <201205270059.04166.rjw@sisk.pl>

On Sun, 27 May 2012, Rafael J. Wysocki wrote:

> So, do you think we should apply [1/4] and [2/4] and try to work around the
> BIOS bug from https://bugzilla.kernel.org/show_bug.cgi?id=43278 (I suppose
> we can do that by double checking if the target state returned by ACPI is
> in agreement with the capabilities returned by the PCI layer)?

Here's one possible approach.  It only solves part of the problem, but
it ought to help with Bugzilla 43278 (Dâniel's case).  I suggest that
we don't believe the output from _SxW if the PCI PM capability
indicates that PME is supported in a higher-numbered D state than _SxW
says.

On Dâniel's smachine, _SxW returns D2 but the controller supports PME 
in D3; therefore we would use D3.

This still leaves the original problem.  It seems clear that ACPI
won't be sufficient to solve this -- at least, it won't help in the
case where the controller isn't enabled for wakeup.

Therefore we really do need a quirk, probably in ehci-hcd like the 
original patch.  If it is restricted to apply only in cases where the 
DMI information lists ASUSTeK as the manufacturer, perhaps that will be 
sufficient.  (For some reason, the manufacturer field in Dâniel's BIOS 
isn't initialized.)

Alan Stern

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

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again)
From: Rafael J. Wysocki @ 2012-05-29 17:29 UTC (permalink / raw)
  To: Alan Stern
  Cc: Oleksij Rempel (fishor), Dâniel Fraga, Andrey Rahmatullin,
	Steven Rostedt, linux-pm, ACPI Devel Mailing List
In-Reply-To: <Pine.LNX.4.44L0.1205291010190.1289-100000@iolanthe.rowland.org>

On Tuesday, May 29, 2012, Alan Stern wrote:
> On Sun, 27 May 2012, Rafael J. Wysocki wrote:
> 
> > So, do you think we should apply [1/4] and [2/4] and try to work around the
> > BIOS bug from https://bugzilla.kernel.org/show_bug.cgi?id=43278 (I suppose
> > we can do that by double checking if the target state returned by ACPI is
> > in agreement with the capabilities returned by the PCI layer)?
> 
> Here's one possible approach.  It only solves part of the problem, but
> it ought to help with Bugzilla 43278 (Dâniel's case).  I suggest that
> we don't believe the output from _SxW if the PCI PM capability
> indicates that PME is supported in a higher-numbered D state than _SxW
> says.
> 
> On Dâniel's smachine, _SxW returns D2

No, it doesn't.  In fact, _SxW is not present for that device in his DSDT.

> but the controller supports PME in D3; therefore we would use D3.

Yes, we can do that.  This goes along the lines of what I said in the bug
entry.

> This still leaves the original problem.  It seems clear that ACPI
> won't be sufficient to solve this -- at least, it won't help in the
> case where the controller isn't enabled for wakeup.
> 
> Therefore we really do need a quirk, probably in ehci-hcd like the 
> original patch.  If it is restricted to apply only in cases where the 
> DMI information lists ASUSTeK as the manufacturer, perhaps that will be 
> sufficient.  (For some reason, the manufacturer field in Dâniel's BIOS 
> isn't initialized.)

Yeah.

I'll have a deeper look at this later today, I think.

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again)
From: Rafael J. Wysocki @ 2012-05-29 17:30 UTC (permalink / raw)
  To: Andrey Rahmatullin
  Cc: Steven Rostedt, Alan Stern, linux-pm, ACPI Devel Mailing List
In-Reply-To: <20120529074852.GF5028@belkar.wrar.name>

On Tuesday, May 29, 2012, Andrey Rahmatullin wrote:
> On Mon, May 28, 2012 at 10:13:01PM +0200, Rafael J. Wysocki wrote:
> > > > > > > > Andrey, Stephen,
> > > > > > > > 
> > > > > > > > We still have problems with this patch in https://bugzilla.kernel.org/show_bug.cgi?id=43278
> > > > > > > > so some more testing will be necessary, I'm afraid.
> > > > > > > > 
> > > > > > > > I will send a series of ACPI and PCI patches I have collected so far,
> > > > > > > > that I'd like you to test on top of kernel 3.4.0 with commit
> > > > > > > > 151b61284776 reverted.
> > > > > > > > 
> > > > > > > > Please let me know if suspend/wakeup work for you with these patches applied.
> > > > > > > I get the usual freeze on suspending with these patches.
> > > > > > 
> > > > > > I see.
> > > > > > 
> > > > > > Please try to unapply [4/4] and see if that helps.
> > > > > It helps.
> > > > 
> > > > Andrey, can you try out Rafael's patches 1-3 (with 151b... reverted)  
> > > > and see what happens if the EHCI controllers' power/wakeup sysfs
> > > > atributes are first set to "disabled"?
> > > It freezes.
> > 
> > Well, that means trying to work around this through changing the algorithm
> > of selecting the target state of a device wasn't a good idea after all.
> > 
> > Still, we've found some bugs in the process, so it was worth the effort.
> > 
> > Please attach the output of dmidecode from your machine.
> Attached.

Cool, thanks!

^ permalink raw reply

* Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor
From: Mike Turquette @ 2012-05-29 17:51 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: eduardo.valentin, kishon, kbaidarov, santosh.shilimkar, tony,
	paul, balbi, amit.kucheria, linux-pm, linux-arm-kernel,
	linux-omap, amit.kachhap, Keerthy
In-Reply-To: <4FC4CBC8.2040600@ti.com>

On 20120529-15:14, Cousson, Benoit wrote:
> On 5/28/2012 1:16 PM, Eduardo Valentin wrote:
> >In fact I didn't touch the clk data on purpose and left the clock handling
> >as is. On my side I didn't know how the clock struct would look like with DT,
> >so, I didn't mess with it.
> >
> >Do you have a reference to check the work in progress for clock DT ?
> 
> Rob sent a pull request, it seems that now it is up to Mike T. :-)
> 
> http://lists-archives.com/linux-kernel/27640907-dt-clk-binding-support.html
> 

Due to the on-going discussion around those patches I haven't pulled
yet.  If everyone agrees once the dust settles then I'll take them in.

Regards,
Mike


^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again)
From: Alan Stern @ 2012-05-29 18:50 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Oleksij Rempel (fishor), Dâniel Fraga, Andrey Rahmatullin,
	Steven Rostedt, linux-pm, ACPI Devel Mailing List
In-Reply-To: <201205291929.41060.rjw@sisk.pl>

On Tue, 29 May 2012, Rafael J. Wysocki wrote:

> On Tuesday, May 29, 2012, Alan Stern wrote:
> > On Sun, 27 May 2012, Rafael J. Wysocki wrote:
> > 
> > > So, do you think we should apply [1/4] and [2/4] and try to work around the
> > > BIOS bug from https://bugzilla.kernel.org/show_bug.cgi?id=43278 (I suppose
> > > we can do that by double checking if the target state returned by ACPI is
> > > in agreement with the capabilities returned by the PCI layer)?
> > 
> > Here's one possible approach.  It only solves part of the problem, but
> > it ought to help with Bugzilla 43278 (Dâniel's case).  I suggest that
> > we don't believe the output from _SxW if the PCI PM capability
> > indicates that PME is supported in a higher-numbered D state than _SxW
> > says.
> > 
> > On Dâniel's smachine, _SxW returns D2
> 
> No, it doesn't.  In fact, _SxW is not present for that device in his DSDT.

Oh -- I guess I got the machines mixed up.  Since _SxW isn't present
and _SxD is, we accept the value of _SxD as the only state in which
wakeup is supported.

ACPI apparently doesn't have any way to express: "The device is allowed 
to be in either D2 or D3 during S3 sleep, but it supports wakeup only 
in D3."  And trying to express the inexpressible, the BIOS ended up 
being buggy.

ACPI also apparently doesn't have any way to express: "The device is 
allowed be in D2 but not D3 during S3 sleep, even if wakeup is not 
enabled."

> > but the controller supports PME in D3; therefore we would use D3.
> 
> Yes, we can do that.  This goes along the lines of what I said in the bug
> entry.
> 
> > This still leaves the original problem.  It seems clear that ACPI
> > won't be sufficient to solve this -- at least, it won't help in the
> > case where the controller isn't enabled for wakeup.
> > 
> > Therefore we really do need a quirk, probably in ehci-hcd like the 
> > original patch.  If it is restricted to apply only in cases where the 
> > DMI information lists ASUSTeK as the manufacturer, perhaps that will be 
> > sufficient.  (For some reason, the manufacturer field in Dâniel's BIOS 
> > isn't initialized.)
> 
> Yeah.
> 
> I'll have a deeper look at this later today, I think.

It's easy enough to write such a check (or perhaps more reliably, check
for a product name matching "P8Z68-V").  More difficult is knowing
whether it's the right thing to do.  We don't know the extent of the
underlying problem.

Alan Stern

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

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: [linux-pm] ehci_hcd related S3 lockup on ASUS laptops, again)
From: Rafael J. Wysocki @ 2012-05-29 19:16 UTC (permalink / raw)
  To: Alan Stern
  Cc: Oleksij Rempel (fishor), Dâniel Fraga, Andrey Rahmatullin,
	Steven Rostedt, linux-pm, ACPI Devel Mailing List
In-Reply-To: <Pine.LNX.4.44L0.1205291425490.1289-100000@iolanthe.rowland.org>

On Tuesday, May 29, 2012, Alan Stern wrote:
> On Tue, 29 May 2012, Rafael J. Wysocki wrote:
> 
> > On Tuesday, May 29, 2012, Alan Stern wrote:
> > > On Sun, 27 May 2012, Rafael J. Wysocki wrote:
> > > 
> > > > So, do you think we should apply [1/4] and [2/4] and try to work around the
> > > > BIOS bug from https://bugzilla.kernel.org/show_bug.cgi?id=43278 (I suppose
> > > > we can do that by double checking if the target state returned by ACPI is
> > > > in agreement with the capabilities returned by the PCI layer)?
> > > 
> > > Here's one possible approach.  It only solves part of the problem, but
> > > it ought to help with Bugzilla 43278 (Dâniel's case).  I suggest that
> > > we don't believe the output from _SxW if the PCI PM capability
> > > indicates that PME is supported in a higher-numbered D state than _SxW
> > > says.
> > > 
> > > On Dâniel's smachine, _SxW returns D2
> > 
> > No, it doesn't.  In fact, _SxW is not present for that device in his DSDT.
> 
> Oh -- I guess I got the machines mixed up.  Since _SxW isn't present
> and _SxD is, we accept the value of _SxD as the only state in which
> wakeup is supported.

Precisely.

> ACPI apparently doesn't have any way to express: "The device is allowed 
> to be in either D2 or D3 during S3 sleep, but it supports wakeup only 
> in D3."  And trying to express the inexpressible, the BIOS ended up 
> being buggy.

Yeah.

> ACPI also apparently doesn't have any way to express: "The device is 
> allowed be in D2 but not D3 during S3 sleep, even if wakeup is not 
> enabled."

That's my understanding too.

> > > but the controller supports PME in D3; therefore we would use D3.
> > 
> > Yes, we can do that.  This goes along the lines of what I said in the bug
> > entry.
> > 
> > > This still leaves the original problem.  It seems clear that ACPI
> > > won't be sufficient to solve this -- at least, it won't help in the
> > > case where the controller isn't enabled for wakeup.
> > > 
> > > Therefore we really do need a quirk, probably in ehci-hcd like the 
> > > original patch.  If it is restricted to apply only in cases where the 
> > > DMI information lists ASUSTeK as the manufacturer, perhaps that will be 
> > > sufficient.  (For some reason, the manufacturer field in Dâniel's BIOS 
> > > isn't initialized.)
> > 
> > Yeah.
> > 
> > I'll have a deeper look at this later today, I think.
> 
> It's easy enough to write such a check (or perhaps more reliably, check
> for a product name matching "P8Z68-V").

I think we should try to express it as a PCI quirk in quirks.c, though.

> More difficult is knowing whether it's the right thing to do.  We don't
> know the extent of the underlying problem.

Well, we can only learn that by experience, so we should address the know
cases and then try to find patterns, if they exist.

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [RFT] PCI changes related to wakeup (was: Re: ehci_hcd related S3 lockup on ASUS laptops, again)
From: Steven Rostedt @ 2012-05-29 22:39 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Andrey Rahmatullin, linux-pm, ACPI Devel Mailing List
In-Reply-To: <201205282213.01560.rjw@sisk.pl>

[-- Attachment #1: Type: text/plain, Size: 172 bytes --]

On Mon, 2012-05-28 at 22:13 +0200, Rafael J. Wysocki wrote:

> Please attach the output of dmidecode from your machine.
> Steven, please do that too.

Attached.

-- Steve


[-- Attachment #2: dmi.gz --]
[-- Type: application/x-gzip, Size: 3391 bytes --]

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH][V3] cpuidle : use percpu cpuidle in the core code
From: Daniel Lezcano @ 2012-05-30  6:51 UTC (permalink / raw)
  To: lenb; +Cc: linux-pm, linaro-dev, Srivatsa S. Bhat, patches
In-Reply-To: <4F7A8F84.5040700@linux.vnet.ibm.com>

On 04/03/2012 07:49 AM, Srivatsa S. Bhat wrote:
> On 04/03/2012 12:50 AM, Daniel Lezcano wrote:
> 
>> The usual cpuidle initialization routines register the driver and
>> then register a cpuidle device per cpu.
>>
>> By default, most drivers initialize the device state count with the
>> driver state count.
>>
>> We can then add a new function 'cpuidle_register' where we register
>> the driver and the devices. These devices can be defined in a global
>> static variable in cpuidle.c. We will be able to factor out and
>> remove a lot of duplicate lines of code.
>>
>> As we still have some drivers, with different initialization routines,
>> we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low
>> level initialization routines to do some specific operations on the
>> cpuidle devices.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> 
> 
> Looks good to me now.
> Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>

Hi Len,

could you consider this patch for merging ?

Thanks
  -- Daniel

> 
> 
> Regards,
> Srivatsa S. Bhat
> 
>> ---
>>  drivers/cpuidle/cpuidle.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/cpuidle.h   |    3 +++
>>  2 files changed, 45 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
>> index 87411ce..4d1f79b 100644
>> --- a/drivers/cpuidle/cpuidle.c
>> +++ b/drivers/cpuidle/cpuidle.c
>> @@ -23,6 +23,7 @@
>>  #include "cpuidle.h"
>>
>>  DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
>> +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device);
>>
>>  DEFINE_MUTEX(cpuidle_lock);
>>  LIST_HEAD(cpuidle_detected_devices);
>> @@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev)
>>
>>  EXPORT_SYMBOL_GPL(cpuidle_register_device);
>>
>> +/*
>> + * cpuidle_register : register cpuidle driver and devices
>> + * Note this function must be called after smp_init.
>> + * @drv : the cpuidle driver
>> + * Returns 0 on success, < 0 otherwise
>> + */
>> +int cpuidle_register(struct cpuidle_driver *drv)
>> +{
>> +	int ret, cpu, i;
>> +	struct cpuidle_device *dev;
>> +
>> +	ret = cpuidle_register_driver(drv);
>> +	if (ret)
>> +		return ret;
>> +
>> +	for_each_online_cpu(cpu) {
>> +		dev = &per_cpu(cpuidle_device, cpu);
>> +		dev->cpu = cpu;
>> +
>> +		ret = cpuidle_register_device(dev);
>> +		if (ret)
>> +			goto out_unregister;
>> +	}
>> +
>> +out:
>> +	return ret;
>> +
>> +out_unregister:
>> +	for_each_online_cpu(i) {
>> +		if (i == cpu)
>> +			break;
>> +		dev = &per_cpu(cpuidle_device, i);
>> +		cpuidle_unregister_device(dev);
>> +	}
>> +
>> +	cpuidle_unregister_driver(drv);
>> +
>> +	goto out;
>> +}
>> +EXPORT_SYMBOL_GPL(cpuidle_register);
>> +
>>  /**
>>   * cpuidle_unregister_device - unregisters a CPU's idle PM feature
>>   * @dev: the cpu
>> diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
>> index 6c26a3d..3475294 100644
>> --- a/include/linux/cpuidle.h
>> +++ b/include/linux/cpuidle.h
>> @@ -135,6 +135,7 @@ struct cpuidle_driver {
>>  #ifdef CONFIG_CPU_IDLE
>>  extern void disable_cpuidle(void);
>>  extern int cpuidle_idle_call(void);
>> +extern int cpuidle_register(struct cpuidle_driver *drv);
>>  extern int cpuidle_register_driver(struct cpuidle_driver *drv);
>>  struct cpuidle_driver *cpuidle_get_driver(void);
>>  extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
>> @@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void);
>>  #else
>>  static inline void disable_cpuidle(void) { }
>>  static inline int cpuidle_idle_call(void) { return -ENODEV; }
>> +static inline int cpuidle_register(struct cpuidle_driver *drv)
>> +{return -ENODEV; }
>>  static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
>>  {return -ENODEV; }
>>  static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
> 
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-pm

^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Cousson, Benoit @ 2012-05-30  8:38 UTC (permalink / raw)
  To: Konstantin Baydarov
  Cc: Eduardo Valentin, kishon, santosh.shilimkar, tony, paul, balbi,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap
In-Reply-To: <4FC49BA5.5050008@dev.rtsoft.ru>

On 5/29/2012 11:49 AM, Konstantin Baydarov wrote:
>    Hi, Eduardo.
>
> On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
>> This patch add device tree entries on OMAP4 based boards
>> for System Control Module (SCM).
>>
>> Signed-off-by: Eduardo Valentin<eduardo.valentin@ti.com>
>> ---
>>   arch/arm/boot/dts/omap4.dtsi |   13 +++++++++++++
>>   1 files changed, 13 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
>> index 359c497..d2cb392 100644
>> --- a/arch/arm/boot/dts/omap4.dtsi
>> +++ b/arch/arm/boot/dts/omap4.dtsi
>> @@ -272,5 +272,18 @@
>>   			ti,hwmods = "mmc5";
>>   			ti,needs-special-reset;
>>   		};
>> +
>> +		ctrl_module_core: ctrl_module_core@4a002000 {
>> +			compatible = "ti,omap4-control";
>> +			ti,hwmods = "ctrl_module_core";
>> +			bandgap {
>> +				compatible = "ti,omap4460-bandgap";
>> +				interrupts =<0 126 4>; /* talert */
>> +				ti,tshut-gpio =<86>; /* tshut */
>> +			};
> I believe that CPU-specific bandgap definition should be moved to bard specific dts.

Mmm, why, since it is CPU specific and not board specific. I has to be 
in the SoC file.

Regards,
Benoit

^ permalink raw reply

* [RFC] the generic thermal layer enhancement
From: Zhang Rui @ 2012-05-30  8:49 UTC (permalink / raw)
  To: Matthew Garrett, Rafael J. Wysocki, Jean Delvare, Brown, Len
  Cc: linux-acpi@vger.kernel.org, linux-pm

Hi, all,

It is great to see more and more users of the generic thermal layer.
But as we know, the original design of the generic thermal layer comes
from ACPI thermal management, and some of its implementation seems to be
too ACPI specific nowadays.

Recently I'm thinking of enhance the generic thermal layer so that it
works well for more platforms.

Below are some thoughts of mine, after reading the patches from Amit
Daniel Kachhap, and ACPI 3.0 thermal model. Actually, I have started
coding some RFC patches. But I do really want to get feedback from you
before going on.

G1. supporting multiple cooling states for active cooling devices.

    The current active cooling device supports two cooling states only,
    please refer to the code below, in driver/thermal/thermal_sys.c
                case THERMAL_TRIP_ACTIVE:
                        ...
                        if (temp >= trip_temp)
                                cdev->ops->set_cur_state(cdev, 1);
                        else
                                cdev->ops->set_cur_state(cdev, 0);
                        break;

    This is an ACPI specific thing, as our ACPI FAN used to support
    ON/OFF only.
    I think it is reasonable to support multiple active cooling states
    as they are common on many platforms, and note that this is also
    true for ACPI 3.0 FAN device (_FPS).

G2. introduce cooling states range for a certain trip point

    This problem comes with the first one.
    If the cooling devices support multiple cooling states, and surely
    we may want only several cooling states for a certain trip point,
    and other cooling states for other active trip points.
    To do this, we should be able to describe the cooling device
    behavior for a certain trip point, rather than for the entire
    thermal zone.

G3. kernel thermal passive cooling algorithm

    Currently, tc1 and tc2 are hard requirements for kernel passive
    cooling. But non-ACPI platforms do not have this information
    (please correct me if I'm wrong).
    Say, for the patches here
    http://marc.info/?l=linux-acpi&m=133681581305341&w=2
    They just want to slow down the processor when current temperature
    is higher than the trip point and speed up the processor when the
    temperature is lower than the trip point.

    According to Matthew, the platform drivers are responsible to
    provide proper tc1 and tc2 values to use kernel passive cooling.
    But I'm just wondering if we can use something instead.
    Say, introduce .get_trend() in thermal_zone_device_ops.
    And we set cur_state++ or cur_state-- based on the value returned
    by .get_trend(), instead of using tc1 and tc2.

G4. Multiple passive trip points

    I get this idea also from the patches at
    http://marc.info/?l=linux-acpi&m=133681581305341&w=2

    IMO, they want to get an acceptable performance at a tolerable
    temperature.
    Say, a platform with four P-states. P3 is really low.
    And I'm okay with the temperature at 60C, but 80C? No.
    With G2 resolved, we can use processor P0~P2 for Passive trip point
    0 (50C), and P3 for Passive trip point 1 (70C). And then the
    temperature may be jumping at around 60C or even 65C, without
    entering P3.

    Further more, IMO, this also works for ACPI platforms.
    Say, we can easily change p-state to cool the system, but using
    t-state is definitely what we do not want to see. The current
    implementation does not expose this difference to the generic
    thermal layer, but if we can have two passive trip points, and use
    p-state for the first one only... (this works if we start polling
    after entering passive cooling mode, without hardware notification)

G5. unify active cooling and passive cooling code

    If G4 and G5 are resolved, a new problem to me is that there is no
    difference between passive cooling and active cooling except the
    cooling policy.
    Then we can share the same code for both active and passive cooling.
    maybe something like:

    case THERMAL_TRIP_ACTIVE:
    case THERMAL_TRIP_PASSIVE:
         ...
         tz->ops->get_trend();
         if (trend == HEATING)
                 cdev->ops->set_cur_state(cdev, cur_state++);
         else if (trend == COOLING)
                 cdev->ops->set_cur_state(cdev, cur_state--);
         break;

Here are the gaps in my point of view, I'd like to get your ideas about
which are reasonable and which are not.

Any comments are appreciated! Thanks!

-rui

^ permalink raw reply

* Re: [linux-pm] [RFC] the generic thermal layer enhancement
From: Zhang Rui @ 2012-05-30  8:51 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Rafael J. Wysocki, Jean Delvare, Brown, Len,
	linux-acpi@vger.kernel.org, linux-pm, Amit Kachhap
In-Reply-To: <1338367742.1472.128.camel@rui.sh.intel.com>

On 三, 2012-05-30 at 16:49 +0800, Zhang Rui wrote:
> Hi, all,
> 
> It is great to see more and more users of the generic thermal layer.
> But as we know, the original design of the generic thermal layer comes
> from ACPI thermal management, and some of its implementation seems to be
> too ACPI specific nowadays.
> 
> Recently I'm thinking of enhance the generic thermal layer so that it
> works well for more platforms.
> 
> Below are some thoughts of mine, after reading the patches from Amit
> Daniel Kachhap, and ACPI 3.0 thermal model. Actually, I have started
> coding some RFC patches. But I do really want to get feedback from you
> before going on.
> 
> G1. supporting multiple cooling states for active cooling devices.
> 
>     The current active cooling device supports two cooling states only,
>     please refer to the code below, in driver/thermal/thermal_sys.c
>                 case THERMAL_TRIP_ACTIVE:
>                         ...
>                         if (temp >= trip_temp)
>                                 cdev->ops->set_cur_state(cdev, 1);
>                         else
>                                 cdev->ops->set_cur_state(cdev, 0);
>                         break;
> 
>     This is an ACPI specific thing, as our ACPI FAN used to support
>     ON/OFF only.
>     I think it is reasonable to support multiple active cooling states
>     as they are common on many platforms, and note that this is also
>     true for ACPI 3.0 FAN device (_FPS).
> 
> G2. introduce cooling states range for a certain trip point
> 
>     This problem comes with the first one.
>     If the cooling devices support multiple cooling states, and surely
>     we may want only several cooling states for a certain trip point,
>     and other cooling states for other active trip points.
>     To do this, we should be able to describe the cooling device
>     behavior for a certain trip point, rather than for the entire
>     thermal zone.
> 
> G3. kernel thermal passive cooling algorithm
> 
>     Currently, tc1 and tc2 are hard requirements for kernel passive
>     cooling. But non-ACPI platforms do not have this information
>     (please correct me if I'm wrong).
>     Say, for the patches here
>     http://marc.info/?l=linux-acpi&m=133681581305341&w=2

Sorry, forgot to cc Amit, the author of this patch set.

thanks,
rui
>     They just want to slow down the processor when current temperature
>     is higher than the trip point and speed up the processor when the
>     temperature is lower than the trip point.
> 
>     According to Matthew, the platform drivers are responsible to
>     provide proper tc1 and tc2 values to use kernel passive cooling.
>     But I'm just wondering if we can use something instead.
>     Say, introduce .get_trend() in thermal_zone_device_ops.
>     And we set cur_state++ or cur_state-- based on the value returned
>     by .get_trend(), instead of using tc1 and tc2.
> 
> G4. Multiple passive trip points
> 
>     I get this idea also from the patches at
>     http://marc.info/?l=linux-acpi&m=133681581305341&w=2
> 
>     IMO, they want to get an acceptable performance at a tolerable
>     temperature.
>     Say, a platform with four P-states. P3 is really low.
>     And I'm okay with the temperature at 60C, but 80C? No.
>     With G2 resolved, we can use processor P0~P2 for Passive trip point
>     0 (50C), and P3 for Passive trip point 1 (70C). And then the
>     temperature may be jumping at around 60C or even 65C, without
>     entering P3.
> 
>     Further more, IMO, this also works for ACPI platforms.
>     Say, we can easily change p-state to cool the system, but using
>     t-state is definitely what we do not want to see. The current
>     implementation does not expose this difference to the generic
>     thermal layer, but if we can have two passive trip points, and use
>     p-state for the first one only... (this works if we start polling
>     after entering passive cooling mode, without hardware notification)
> 
> G5. unify active cooling and passive cooling code
> 
>     If G4 and G5 are resolved, a new problem to me is that there is no
>     difference between passive cooling and active cooling except the
>     cooling policy.
>     Then we can share the same code for both active and passive cooling.
>     maybe something like:
> 
>     case THERMAL_TRIP_ACTIVE:
>     case THERMAL_TRIP_PASSIVE:
>          ...
>          tz->ops->get_trend();
>          if (trend == HEATING)
>                  cdev->ops->set_cur_state(cdev, cur_state++);
>          else if (trend == COOLING)
>                  cdev->ops->set_cur_state(cdev, cur_state--);
>          break;
> 
> Here are the gaps in my point of view, I'd like to get your ideas about
> which are reasonable and which are not.
> 
> Any comments are appreciated! Thanks!
> 
> -rui
> 
> _______________________________________________
> linux-pm mailing list
> linux-pm@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/linux-pm


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

^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Konstantin Baydarov @ 2012-05-30  9:05 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: Eduardo Valentin, kishon, santosh.shilimkar, tony, paul, balbi,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap, Konstantin Baydarov
In-Reply-To: <4FC5DC9F.7080104@ti.com>

On 05/30/2012 12:38 PM, Cousson, Benoit wrote:
> On 5/29/2012 11:49 AM, Konstantin Baydarov wrote:
>>    Hi, Eduardo.
>>
>> On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
>>> This patch add device tree entries on OMAP4 based boards
>>> for System Control Module (SCM).
>>>
>>> Signed-off-by: Eduardo Valentin<eduardo.valentin@ti.com>
>>> ---
>>>   arch/arm/boot/dts/omap4.dtsi |   13 +++++++++++++
>>>   1 files changed, 13 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
>>> index 359c497..d2cb392 100644
>>> --- a/arch/arm/boot/dts/omap4.dtsi
>>> +++ b/arch/arm/boot/dts/omap4.dtsi
>>> @@ -272,5 +272,18 @@
>>>               ti,hwmods = "mmc5";
>>>               ti,needs-special-reset;
>>>           };
>>> +
>>> +        ctrl_module_core: ctrl_module_core@4a002000 {
>>> +            compatible = "ti,omap4-control";
>>> +            ti,hwmods = "ctrl_module_core";
>>> +            bandgap {
>>> +                compatible = "ti,omap4460-bandgap";
>>> +                interrupts =<0 126 4>; /* talert */
>>> +                ti,tshut-gpio =<86>; /* tshut */
>>> +            };
>> I believe that CPU-specific bandgap definition should be moved to bard specific dts.
>
> Mmm, why, since it is CPU specific and not board specific. I has to be in the SoC file.
Speaking about omap4430 - omap4430 bandgap differs from omap4460, so if omap4430 bandgap support will be added to omap-bandgap driver the version of bandgap should specified in dts file. omap4.dtsi is a common for omap4 boards, that is why I'm suggesting to move bandgap description to probably board specific file.
Another solution is to determine bandgap type in driver probe function, but in that case "ti,omap4460-bandgap" in omap4.dtsi should be replaced to "ti,omap4-bandgap".

  BR,
    Konstantin Baydarov.

> Regards,
> Benoit


^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Cousson, Benoit @ 2012-05-30  9:26 UTC (permalink / raw)
  To: Konstantin Baydarov
  Cc: balbi, kishon, amit.kucheria, linux-pm, linux-omap,
	linux-arm-kernel
In-Reply-To: <4FC5E2EE.8030504@dev.rtsoft.ru>

On 5/30/2012 11:05 AM, Konstantin Baydarov wrote:
> On 05/30/2012 12:38 PM, Cousson, Benoit wrote:
>> On 5/29/2012 11:49 AM, Konstantin Baydarov wrote:
>>> Hi, Eduardo.
>>>
>>> On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
>>>> This patch add device tree entries on OMAP4 based boards for
>>>> System Control Module (SCM).

...

>>> I believe that CPU-specific bandgap definition should be moved to
>>> bard specific dts.
>>
>> Mmm, why, since it is CPU specific and not board specific. I has to
>> be in the SoC file.
> Speaking about omap4430 - omap4430 bandgap differs from omap4460, so
> if omap4430 bandgap support will be added to omap-bandgap driver the
> version of bandgap should specified in dts file. omap4.dtsi is a
> common for omap4 boards, that is why I'm suggesting to move bandgap
> description to probably board specific file.

OK, I got your point, but in that case we could potentially define a 
omap4460.dtsi file.

> Another solution is to
> determine bandgap type in driver probe function, but in that case
> "ti,omap4460-bandgap" in omap4.dtsi should be replaced to
> "ti,omap4-bandgap".

Yes, this is the best solution, but that assume that we can identify the 
control module version from the HW, which is not necessarily true :-(

The IP_REVISION (offset = 0) value are unfortunately not documented, so 
we should read it to check if they are different from omap4430 and 4460.

The bitfield layout in that register is:

IP_REV_MAJOR: 8..10
IP_REV_CUSTOM: 6..7
IP_REV_MINOR: 0..5

Regards,
Benoit

^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Konstantin Baydarov @ 2012-05-30 10:17 UTC (permalink / raw)
  To: Cousson, Benoit
  Cc: Eduardo Valentin, kishon, santosh.shilimkar, tony, paul, balbi,
	amit.kucheria, linux-pm, linux-arm-kernel, linux-omap,
	amit.kachhap
In-Reply-To: <4FC5E7DE.2060905@ti.com>

  Hi.
On 05/30/2012 01:26 PM, Cousson, Benoit wrote:
> On 5/30/2012 11:05 AM, Konstantin Baydarov wrote:
>> On 05/30/2012 12:38 PM, Cousson, Benoit wrote:
>>> On 5/29/2012 11:49 AM, Konstantin Baydarov wrote:
>>>> Hi, Eduardo.
>>>>
>>>> On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
>>>>> This patch add device tree entries on OMAP4 based boards for
>>>>> System Control Module (SCM).
>
> ...
>
>>>> I believe that CPU-specific bandgap definition should be moved to
>>>> bard specific dts.
>>>
>>> Mmm, why, since it is CPU specific and not board specific. I has to
>>> be in the SoC file.
>> Speaking about omap4430 - omap4430 bandgap differs from omap4460, so
>> if omap4430 bandgap support will be added to omap-bandgap driver the
>> version of bandgap should specified in dts file. omap4.dtsi is a
>> common for omap4 boards, that is why I'm suggesting to move bandgap
>> description to probably board specific file.
>
> OK, I got your point, but in that case we could potentially define a omap4460.dtsi file.
>
>> Another solution is to
>> determine bandgap type in driver probe function, but in that case
>> "ti,omap4460-bandgap" in omap4.dtsi should be replaced to
>> "ti,omap4-bandgap".
>
> Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
>
> The IP_REVISION (offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.
>
> The bitfield layout in that register is:
>
> IP_REV_MAJOR: 8..10
> IP_REV_CUSTOM: 6..7
> IP_REV_MINOR: 0..5
Probably, cpu_is_omap443x() and cpu_is_omap446x() can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():
drivers/mfd/omap-usb-host.c
drivers/mfd/twl-core.c

  BR,
    Konstantin Baydarov.

>
> Regards,
> Benoit


^ permalink raw reply

* Re: [RFC PATCH 11/11] ARM: DT: Add support to system control module for OMAP4
From: Cousson, Benoit @ 2012-05-30 10:22 UTC (permalink / raw)
  To: Konstantin Baydarov
  Cc: balbi, kishon, amit.kucheria, linux-pm, linux-omap,
	linux-arm-kernel
In-Reply-To: <4FC5F3C3.2000309@dev.rtsoft.ru>

On 5/30/2012 12:17 PM, Konstantin Baydarov wrote:
>    Hi.
> On 05/30/2012 01:26 PM, Cousson, Benoit wrote:
>> On 5/30/2012 11:05 AM, Konstantin Baydarov wrote:
>>> On 05/30/2012 12:38 PM, Cousson, Benoit wrote:
>>>> On 5/29/2012 11:49 AM, Konstantin Baydarov wrote:
>>>>> Hi, Eduardo.
>>>>>
>>>>> On 05/25/2012 12:26 PM, Eduardo Valentin wrote:
>>>>>> This patch add device tree entries on OMAP4 based boards for
>>>>>> System Control Module (SCM).
>>
>> ...
>>
>>>>> I believe that CPU-specific bandgap definition should be moved to
>>>>> bard specific dts.
>>>>
>>>> Mmm, why, since it is CPU specific and not board specific. I has to
>>>> be in the SoC file.
>>> Speaking about omap4430 - omap4430 bandgap differs from omap4460, so
>>> if omap4430 bandgap support will be added to omap-bandgap driver the
>>> version of bandgap should specified in dts file. omap4.dtsi is a
>>> common for omap4 boards, that is why I'm suggesting to move bandgap
>>> description to probably board specific file.
>>
>> OK, I got your point, but in that case we could potentially define a omap4460.dtsi file.
>>
>>> Another solution is to
>>> determine bandgap type in driver probe function, but in that case
>>> "ti,omap4460-bandgap" in omap4.dtsi should be replaced to
>>> "ti,omap4-bandgap".
>>
>> Yes, this is the best solution, but that assume that we can identify the control module version from the HW, which is not necessarily true :-(
>>
>> The IP_REVISION (offset = 0) value are unfortunately not documented, so we should read it to check if they are different from omap4430 and 4460.
>>
>> The bitfield layout in that register is:
>>
>> IP_REV_MAJOR: 8..10
>> IP_REV_CUSTOM: 6..7
>> IP_REV_MINOR: 0..5
> Probably, cpu_is_omap443x() and cpu_is_omap446x() can be used in bandgap driver probe function. Actually many drivers use cpu_is_omap*():

No, we cannot, we are in the process of getting rid of that.
A driver should only focus on the IP version in theory. The CPU version 
is not the proper way of getting that. It will make the driver not 
scalable at all for future OMAP revision.

> drivers/mfd/omap-usb-host.c
> drivers/mfd/twl-core.c

Yeah, these are the ones that still need to be fixed...

Regards,
Benoit

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox