* Re: [PATCH v6 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio()
From: Rafael J. Wysocki @ 2012-11-27 21:46 UTC (permalink / raw)
To: linux-pm
Cc: Ming Lei, linux-kernel, Alan Stern, Oliver Neukum, Minchan Kim,
Greg Kroah-Hartman, Jens Axboe, David S. Miller, Andrew Morton,
netdev, linux-usb, linux-mm
In-Reply-To: <5434404.G1ERYjuorE@vostro.rjw.lan>
On Tuesday, November 27, 2012 10:19:29 PM Rafael J. Wysocki wrote:
> On Saturday, November 24, 2012 08:59:14 PM Ming Lei wrote:
> > The patch introduces the flag of memalloc_noio in 'struct dev_pm_info'
> > to help PM core to teach mm not allocating memory with GFP_KERNEL
> > flag for avoiding probable deadlock.
> >
> > As explained in the comment, any GFP_KERNEL allocation inside
> > runtime_resume() or runtime_suspend() on any one of device in
> > the path from one block or network device to the root device
> > in the device tree may cause deadlock, the introduced
> > pm_runtime_set_memalloc_noio() sets or clears the flag on
> > device in the path recursively.
> >
> > Cc: Alan Stern <stern@rowland.harvard.edu>
> > Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
> > Signed-off-by: Ming Lei <ming.lei@canonical.com>
> > ---
> > v5:
> > - fix code style error
> > - add comment on clear the device memalloc_noio flag
> > v4:
> > - rename memalloc_noio_resume as memalloc_noio
> > - remove pm_runtime_get_memalloc_noio()
> > - add comments on pm_runtime_set_memalloc_noio
> > v3:
> > - introduce pm_runtime_get_memalloc_noio()
> > - hold one global lock on pm_runtime_set_memalloc_noio
> > - hold device power lock when accessing memalloc_noio_resume
> > flag suggested by Alan Stern
> > - implement pm_runtime_set_memalloc_noio without recursion
> > suggested by Alan Stern
> > v2:
> > - introduce pm_runtime_set_memalloc_noio()
> > ---
> > drivers/base/power/runtime.c | 60 ++++++++++++++++++++++++++++++++++++++++++
> > include/linux/pm.h | 1 +
> > include/linux/pm_runtime.h | 3 +++
> > 3 files changed, 64 insertions(+)
> >
> > diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> > index 3148b10..3e198a0 100644
> > --- a/drivers/base/power/runtime.c
> > +++ b/drivers/base/power/runtime.c
> > @@ -124,6 +124,66 @@ unsigned long pm_runtime_autosuspend_expiration(struct device *dev)
> > }
> > EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration);
> >
> > +static int dev_memalloc_noio(struct device *dev, void *data)
> > +{
> > + return dev->power.memalloc_noio;
> > +}
> > +
> > +/*
> > + * pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag.
> > + * @dev: Device to handle.
> > + * @enable: True for setting the flag and False for clearing the flag.
> > + *
> > + * Set the flag for all devices in the path from the device to the
> > + * root device in the device tree if @enable is true, otherwise clear
> > + * the flag for devices in the path whose siblings don't set the flag.
> > + *
>
> Please use counters instead of walking the whole path every time. Ie. in
> addition to the flag add a counter to store the number of the device's
> children having that flag set.
I would use the flag only to store the information that
pm_runtime_set_memalloc_noio(dev, true) has been run for this device directly
and I'd use a counter for everything else.
That is, have power.memalloc_count that would be incremented when (1)
pm_runtime_set_memalloc_noio(dev, true) is called for that device and (2) when
power.memalloc_count for one of its children changes from 0 to 1 (and
analogously for decrementation). Then, check the counter in rpm_callback().
Thanks,
Rafael
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH v6 5/6] PM / Runtime: force memory allocation with no I/O during Runtime PM callbcack
From: Rafael J. Wysocki @ 2012-11-27 21:24 UTC (permalink / raw)
To: linux-pm
Cc: Ming Lei, linux-kernel, Alan Stern, Oliver Neukum, Minchan Kim,
Greg Kroah-Hartman, Jens Axboe, David S. Miller, Andrew Morton,
netdev, linux-usb, linux-mm
In-Reply-To: <1353761958-12810-6-git-send-email-ming.lei@canonical.com>
On Saturday, November 24, 2012 08:59:17 PM Ming Lei wrote:
> This patch applies the introduced memalloc_noio_save() and
> memalloc_noio_restore() to force memory allocation with no I/O
> during runtime_resume/runtime_suspend callback on device with
> the flag of 'memalloc_noio' set.
>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Oliver Neukum <oneukum@suse.de>
> Cc: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
> v5:
> - use inline memalloc_noio_save()
> v4:
> - runtime_suspend need this too because rpm_resume may wait for
> completion of concurrent runtime_suspend, so deadlock still may
> be triggered in runtime_suspend path.
> ---
> drivers/base/power/runtime.c | 32 ++++++++++++++++++++++++++++++--
> 1 file changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 3e198a0..96d99ea 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -371,6 +371,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
> int (*callback)(struct device *);
> struct device *parent = NULL;
> int retval;
> + unsigned int noio_flag;
>
> trace_rpm_suspend(dev, rpmflags);
>
> @@ -480,7 +481,20 @@ static int rpm_suspend(struct device *dev, int rpmflags)
> if (!callback && dev->driver && dev->driver->pm)
> callback = dev->driver->pm->runtime_suspend;
>
> - retval = rpm_callback(callback, dev);
> + /*
> + * Deadlock might be caused if memory allocation with GFP_KERNEL
> + * happens inside runtime_suspend callback of one block device's
> + * ancestor or the block device itself. Network device might be
> + * thought as part of iSCSI block device, so network device and
> + * its ancestor should be marked as memalloc_noio.
> + */
> + if (dev->power.memalloc_noio) {
> + noio_flag = memalloc_noio_save();
> + retval = rpm_callback(callback, dev);
> + memalloc_noio_restore(noio_flag);
> + } else {
> + retval = rpm_callback(callback, dev);
> + }
> if (retval)
> goto fail;
>
> @@ -563,6 +577,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
> int (*callback)(struct device *);
> struct device *parent = NULL;
> int retval = 0;
> + unsigned int noio_flag;
>
> trace_rpm_resume(dev, rpmflags);
>
> @@ -712,7 +727,20 @@ static int rpm_resume(struct device *dev, int rpmflags)
> if (!callback && dev->driver && dev->driver->pm)
> callback = dev->driver->pm->runtime_resume;
>
> - retval = rpm_callback(callback, dev);
> + /*
> + * Deadlock might be caused if memory allocation with GFP_KERNEL
> + * happens inside runtime_resume callback of one block device's
> + * ancestor or the block device itself. Network device might be
> + * thought as part of iSCSI block device, so network device and
> + * its ancestor should be marked as memalloc_noio.
> + */
> + if (dev->power.memalloc_noio) {
> + noio_flag = memalloc_noio_save();
> + retval = rpm_callback(callback, dev);
> + memalloc_noio_restore(noio_flag);
> + } else {
> + retval = rpm_callback(callback, dev);
> + }
Please don't duplicate code this way.
You can move that whole thing to rpm_callback(). Yes, you'll probably need to
check dev->power.memalloc_noio twice in there, but that's OK.
> if (retval) {
> __update_runtime_status(dev, RPM_SUSPENDED);
> pm_runtime_cancel_pending(dev);
>
Thanks,
Rafael
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH v6 2/6] PM / Runtime: introduce pm_runtime_set_memalloc_noio()
From: Rafael J. Wysocki @ 2012-11-27 21:19 UTC (permalink / raw)
To: linux-pm
Cc: Ming Lei, linux-kernel, Alan Stern, Oliver Neukum, Minchan Kim,
Greg Kroah-Hartman, Jens Axboe, David S. Miller, Andrew Morton,
netdev, linux-usb, linux-mm
In-Reply-To: <1353761958-12810-3-git-send-email-ming.lei@canonical.com>
On Saturday, November 24, 2012 08:59:14 PM Ming Lei wrote:
> The patch introduces the flag of memalloc_noio in 'struct dev_pm_info'
> to help PM core to teach mm not allocating memory with GFP_KERNEL
> flag for avoiding probable deadlock.
>
> As explained in the comment, any GFP_KERNEL allocation inside
> runtime_resume() or runtime_suspend() on any one of device in
> the path from one block or network device to the root device
> in the device tree may cause deadlock, the introduced
> pm_runtime_set_memalloc_noio() sets or clears the flag on
> device in the path recursively.
>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
> v5:
> - fix code style error
> - add comment on clear the device memalloc_noio flag
> v4:
> - rename memalloc_noio_resume as memalloc_noio
> - remove pm_runtime_get_memalloc_noio()
> - add comments on pm_runtime_set_memalloc_noio
> v3:
> - introduce pm_runtime_get_memalloc_noio()
> - hold one global lock on pm_runtime_set_memalloc_noio
> - hold device power lock when accessing memalloc_noio_resume
> flag suggested by Alan Stern
> - implement pm_runtime_set_memalloc_noio without recursion
> suggested by Alan Stern
> v2:
> - introduce pm_runtime_set_memalloc_noio()
> ---
> drivers/base/power/runtime.c | 60 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/pm.h | 1 +
> include/linux/pm_runtime.h | 3 +++
> 3 files changed, 64 insertions(+)
>
> diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
> index 3148b10..3e198a0 100644
> --- a/drivers/base/power/runtime.c
> +++ b/drivers/base/power/runtime.c
> @@ -124,6 +124,66 @@ unsigned long pm_runtime_autosuspend_expiration(struct device *dev)
> }
> EXPORT_SYMBOL_GPL(pm_runtime_autosuspend_expiration);
>
> +static int dev_memalloc_noio(struct device *dev, void *data)
> +{
> + return dev->power.memalloc_noio;
> +}
> +
> +/*
> + * pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag.
> + * @dev: Device to handle.
> + * @enable: True for setting the flag and False for clearing the flag.
> + *
> + * Set the flag for all devices in the path from the device to the
> + * root device in the device tree if @enable is true, otherwise clear
> + * the flag for devices in the path whose siblings don't set the flag.
> + *
Please use counters instead of walking the whole path every time. Ie. in
addition to the flag add a counter to store the number of the device's
children having that flag set.
Besides, don't you need to check children for the arg device itself?
> + * The function should only be called by block device, or network
> + * device driver for solving the deadlock problem during runtime
> + * resume/suspend:
> + *
> + * If memory allocation with GFP_KERNEL is called inside runtime
> + * resume/suspend callback of any one of its ancestors(or the
> + * block device itself), the deadlock may be triggered inside the
> + * memory allocation since it might not complete until the block
> + * device becomes active and the involed page I/O finishes. The
> + * situation is pointed out first by Alan Stern. Network device
> + * are involved in iSCSI kind of situation.
> + *
> + * The lock of dev_hotplug_mutex is held in the function for handling
> + * hotplug race because pm_runtime_set_memalloc_noio() may be called
> + * in async probe().
> + *
> + * The function should be called between device_add() and device_del()
> + * on the affected device(block/network device).
> + */
> +void pm_runtime_set_memalloc_noio(struct device *dev, bool enable)
> +{
> + static DEFINE_MUTEX(dev_hotplug_mutex);
What's the mutex for?
> +
> + mutex_lock(&dev_hotplug_mutex);
> + for (;;) {
> + /* hold power lock since bitfield is not SMP-safe. */
> + spin_lock_irq(&dev->power.lock);
> + dev->power.memalloc_noio = enable;
> + spin_unlock_irq(&dev->power.lock);
> +
> + dev = dev->parent;
> +
> + /*
> + * clear flag of the parent device only if all the
> + * children don't set the flag because ancestor's
> + * flag was set by any one of the descendants.
> + */
> + if (!dev || (!enable &&
> + device_for_each_child(dev, NULL,
> + dev_memalloc_noio)))
> + break;
> + }
> + mutex_unlock(&dev_hotplug_mutex);
> +}
> +EXPORT_SYMBOL_GPL(pm_runtime_set_memalloc_noio);
> +
> /**
> * rpm_check_suspend_allowed - Test whether a device may be suspended.
> * @dev: Device to test.
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 03d7bb1..1a8a69d 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -538,6 +538,7 @@ struct dev_pm_info {
> unsigned int irq_safe:1;
> unsigned int use_autosuspend:1;
> unsigned int timer_autosuspends:1;
> + unsigned int memalloc_noio:1;
> enum rpm_request request;
> enum rpm_status runtime_status;
> int runtime_error;
> diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
> index f271860..775e063 100644
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -47,6 +47,7 @@ extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);
> extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev);
> extern void pm_runtime_update_max_time_suspended(struct device *dev,
> s64 delta_ns);
> +extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
>
> static inline bool pm_children_suspended(struct device *dev)
> {
> @@ -149,6 +150,8 @@ static inline void pm_runtime_set_autosuspend_delay(struct device *dev,
> int delay) {}
> static inline unsigned long pm_runtime_autosuspend_expiration(
> struct device *dev) { return 0; }
> +static inline void pm_runtime_set_memalloc_noio(struct device *dev,
> + bool enable){}
>
> #endif /* !CONFIG_PM_RUNTIME */
>
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH v6 0/6] solve deadlock caused by memory allocation with I/O
From: Andrew Morton @ 2012-11-27 20:25 UTC (permalink / raw)
To: Ming Lei
Cc: linux-kernel, Alan Stern, Oliver Neukum, Minchan Kim,
Greg Kroah-Hartman, Rafael J. Wysocki, Jens Axboe,
David S. Miller, netdev, linux-usb, linux-pm, linux-mm
In-Reply-To: <1353761958-12810-1-git-send-email-ming.lei@canonical.com>
On Sat, 24 Nov 2012 20:59:12 +0800
Ming Lei <ming.lei@canonical.com> wrote:
> This patchset try to solve one deadlock problem which might be caused
> by memory allocation with block I/O during runtime PM and block device
> error handling path. Traditionly, the problem is addressed by passing
> GFP_NOIO statically to mm, but that is not a effective solution, see
> detailed description in patch 1's commit log.
>
> This patch set introduces one process flag and trys to fix the deadlock
> problem on block device/network device during runtime PM or usb bus reset.
>
> The 1st one is the change on include/sched.h and mm.
>
> The 2nd patch introduces the flag of memalloc_noio on 'dev_pm_info',
> and pm_runtime_set_memalloc_noio(), so that PM Core can teach mm to not
> allocate mm with GFP_IO during the runtime_resume callback only on
> device with the flag set.
>
> The following 2 patches apply the introduced pm_runtime_set_memalloc_noio()
> to mark all devices as memalloc_noio_resume in the path from the block or
> network device to the root device in device tree.
>
> The last 2 patches are applied again PM and USB subsystem to demonstrate
> how to use the introduced mechanism to fix the deadlock problem.
>
> Andrew, could you queue these patches into your tree since V6 fixes all
> your concerns and looks no one objects these patches?
Yes, this patchset looks ready to run with. But as we're at -rc7 I'll ask
you to refresh, retest and resend after 3.8-rc1, please.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH 1/6 v6] arm: use devicetree to get smp_twd clock
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel
Cc: Mark Langsdorf, Rob Herring
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf@calxeda.com>
From: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
---
Changes from v4, v5
None.
Changes from v3
No longer setting *clk to NULL in twd_get_clock().
Changes from v2
Turned the check for the node pointer into an if-then-else statement.
Removed the second, redundant clk_get_rate.
Changes from v1
None.
arch/arm/kernel/smp_twd.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index b22d700..af46b80 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -237,12 +237,15 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
return IRQ_NONE;
}
-static struct clk *twd_get_clock(void)
+static struct clk *twd_get_clock(struct device_node *np)
{
struct clk *clk;
int err;
- clk = clk_get_sys("smp_twd", NULL);
+ if (np)
+ clk = of_clk_get(np, 0);
+ else
+ clk = clk_get_sys("smp_twd", NULL);
if (IS_ERR(clk)) {
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
return clk;
@@ -263,6 +266,7 @@ static struct clk *twd_get_clock(void)
return ERR_PTR(err);
}
+ twd_timer_rate = clk_get_rate(clk);
return clk;
}
@@ -273,12 +277,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
struct clock_event_device **this_cpu_clk;
- if (!twd_clk)
- twd_clk = twd_get_clock();
-
- if (!IS_ERR_OR_NULL(twd_clk))
- twd_timer_rate = clk_get_rate(twd_clk);
- else
+ if (IS_ERR_OR_NULL(twd_clk))
twd_calibrate_rate();
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
@@ -349,6 +348,8 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
if (!twd_base)
return -ENOMEM;
+ twd_clk = twd_get_clock(NULL);
+
return twd_local_timer_common_register();
}
@@ -383,6 +384,8 @@ void __init twd_local_timer_of_register(void)
goto out;
}
+ twd_clk = twd_get_clock(np);
+
err = twd_local_timer_common_register();
out:
--
1.7.11.7
^ permalink raw reply related
* [PATCH 0/6 v6] cpufreq: add support for Calxeda ECX-1000 (highbank)
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel
In-Reply-To: <1351631056-25938-1-git-send-email-mark.langsdorf@calxeda.com>
This patch series adds cpufreq support for the Calxeda
ECX-1000 (highbank) SoCs. The driver is based on the
cpufreq-cpu0 driver. Because of the unique way that
highbank uses the EnergyCore Management Engine to manage
voltages, it was not possible to use the cpufreq-cpu0 driver.
--Mark Langsdorf
^ permalink raw reply
* [PATCH 6/6 v6] cpufreq, highbank: add support for highbank cpufreq
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
cpufreq-u79uwXL29TY76Z2rM5mHXA, linux-pm-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Mark Langsdorf
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
Highbank processors depend on the external ECME to perform voltage
management based on a requested frequency. Communication between the
A9 cores and the ECME happens over the pl320 IPC channel.
Signed-off-by: Mark Langsdorf <mark.langsdorf-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
---
Changes from v5
Changed ipc_transmit() to pl320_ipc_transmit().
Changes from v4
Removed erroneous changes to arch/arm/Kconfig.
Removed unnecessary changes to drivers/cpufreq/Kconfig.arm
Alphabetized additions to arch/arm/mach-highbank/Kconfig
Changed ipc call and header to match new ipc location in
drivers/mailbox.
Changes from v3
None.
Changes from v2
Changed transition latency binding in code to match documentation.
Changes from v1
Added highbank specific Kconfig changes.
.../bindings/cpufreq/highbank-cpufreq.txt | 53 +++++
arch/arm/boot/dts/highbank.dts | 10 +
arch/arm/mach-highbank/Kconfig | 2 +
drivers/cpufreq/Kconfig.arm | 13 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/highbank-cpufreq.c | 229 +++++++++++++++++++++
6 files changed, 308 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cpufreq/highbank-cpufreq.txt
create mode 100644 drivers/cpufreq/highbank-cpufreq.c
diff --git a/Documentation/devicetree/bindings/cpufreq/highbank-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/highbank-cpufreq.txt
new file mode 100644
index 0000000..1d5a836
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/highbank-cpufreq.txt
@@ -0,0 +1,53 @@
+Highbank cpufreq driver
+
+This is cpufreq driver for Calxeda ECX-1000 (highbank) processor. It is based
+on the generic cpu0 driver and uses a similar format for bindings. Since
+the EnergyCore Management Engine maintains the voltage based on the
+frequency, the voltage component of the operating points can be set to any
+arbitrary values.
+
+Both required properties listed below must be defined under node /cpus/cpu@0.
+
+Required properties:
+- operating-points: Refer to Documentation/devicetree/bindings/power/opp.txt
+ for details
+- transition-latency: Specify the possible maximum transition latency for clock,
+ in unit of nanoseconds.
+
+Examples:
+
+cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz ignored */
+ 790000 1000000
+ 396000 1000000
+ 198000 1000000
+ >;
+ transition-latency = <200000>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 0c6fc34..8624c94 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -36,6 +36,16 @@
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
+ operating-points = <
+ /* kHz ignored */
+ 1300000 1000000
+ 1200000 1000000
+ 1100000 1000000
+ 800000 1000000
+ 400000 1000000
+ 200000 1000000
+ >;
+ transition-latency = <100000>;
};
cpu@1 {
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 2896881..b7862da 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -1,5 +1,7 @@
config ARCH_HIGHBANK
bool "Calxeda ECX-1000 (Highbank)" if ARCH_MULTI_V7
+ select ARCH_HAS_CPUFREQ
+ select ARCH_HAS_OPP
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
select ARM_GIC
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 5961e64..7a8bcdc 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -76,3 +76,16 @@ config ARM_EXYNOS5250_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.
+
+config ARM_HIGHBANK_CPUFREQ
+ tristate "Calxeda Highbank-based"
+ depends on ARCH_HIGHBANK
+ select CPU_FREQ_TABLE
+ select PM_OPP
+ default m
+ help
+ This adds the CPUFreq driver for Calxeda Highbank SoC
+ based boards.
+
+ If in doubt, say N.
+
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 1bc90e1..9e8f12a 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
+obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
new file mode 100644
index 0000000..878d3ff
--- /dev/null
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2012 Calxeda, Inc.
+ *
+ * derived from cpufreq-cpu0 by Freescale Semiconductor
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/opp.h>
+#include <linux/slab.h>
+#include <linux/mailbox.h>
+
+#define HB_CPUFREQ_CHANGE_NOTE 0x80000001
+
+static unsigned int transition_latency;
+
+static struct device *cpu_dev;
+static struct clk *cpu_clk;
+static struct cpufreq_frequency_table *freq_table;
+
+static int hb_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int hb_get_speed(unsigned int cpu)
+{
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int hb_voltage_change(unsigned int freq)
+{
+ int i;
+ u32 msg[7];
+
+ msg[0] = HB_CPUFREQ_CHANGE_NOTE;
+ msg[1] = freq / 1000;
+ for (i = 2; i < 7; i++)
+ msg[i] = 0;
+
+ return pl320_ipc_transmit(msg);
+}
+
+static int hb_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned long freq_Hz;
+ unsigned int index, cpu;
+ int ret;
+
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &index);
+ if (ret) {
+ pr_err("failed to match target freqency %d: %d\n",
+ target_freq, ret);
+ return ret;
+ }
+
+ freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
+ if (freq_Hz < 0)
+ freq_Hz = freq_table[index].frequency * 1000;
+ freqs.new = freq_Hz / 1000;
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ for_each_online_cpu(cpu) {
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+ pr_debug("%u MHz --> %u MHz\n", freqs.old / 1000, freqs.new / 1000);
+
+ /* scaling up? scale voltage before frequency */
+ if (freqs.new > freqs.old) {
+ ret = hb_voltage_change(freqs.new);
+ if (ret) {
+ freqs.new = freqs.old;
+ return -EAGAIN;
+ }
+ }
+
+ ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+ if (ret) {
+ pr_err("failed to set clock rate: %d\n", ret);
+ hb_voltage_change(freqs.old);
+ return ret;
+ }
+
+ /* scaling down? scale voltage after frequency */
+ if (freqs.new < freqs.old) {
+ ret = hb_voltage_change(freqs.new);
+ if (ret) {
+ if (clk_set_rate(cpu_clk, freqs.old * 1000))
+ pr_err("also failed to reset freq\n");
+ freqs.new = freqs.old;
+ return -EAGAIN;
+ }
+ }
+
+ for_each_online_cpu(cpu) {
+ freqs.cpu = cpu;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+ return 0;
+}
+
+static int hb_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (ret) {
+ pr_err("invalid frequency table: %d\n", ret);
+ return ret;
+ }
+
+ policy->cpuinfo.transition_latency = transition_latency;
+ policy->cur = clk_get_rate(cpu_clk) / 1000;
+
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_setall(policy->cpus);
+
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+ return 0;
+}
+
+static int hb_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+
+ return 0;
+}
+
+static struct freq_attr *hb_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver hb_cpufreq_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = hb_verify_speed,
+ .target = hb_set_target,
+ .get = hb_get_speed,
+ .init = hb_cpufreq_init,
+ .exit = hb_cpufreq_exit,
+ .name = "highbank-cpufreq",
+ .attr = hb_cpufreq_attr,
+};
+
+static int __devinit hb_cpufreq_driver_init(void)
+{
+ struct device_node *np;
+ int ret;
+
+ np = of_find_node_by_path("/cpus/cpu@0");
+ if (!np) {
+ pr_err("failed to find highbank cpufreq node\n");
+ return -ENOENT;
+ }
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev) {
+ pr_err("failed to get highbank cpufreq device\n");
+ ret = -ENODEV;
+ goto out_put_node;
+ }
+
+ cpu_dev->of_node = np;
+
+ cpu_clk = clk_get(cpu_dev, NULL);
+ if (IS_ERR(cpu_clk)) {
+ ret = PTR_ERR(cpu_clk);
+ pr_err("failed to get cpu0 clock: %d\n", ret);
+ goto out_put_node;
+ }
+
+ ret = of_init_opp_table(cpu_dev);
+ if (ret) {
+ pr_err("failed to init OPP table: %d\n", ret);
+ goto out_put_node;
+ }
+
+ ret = opp_init_cpufreq_table(cpu_dev, &freq_table);
+ if (ret) {
+ pr_err("failed to init cpufreq table: %d\n", ret);
+ goto out_put_node;
+ }
+
+ if (of_property_read_u32(np, "transition-latency", &transition_latency))
+ transition_latency = CPUFREQ_ETERNAL;
+
+ ret = cpufreq_register_driver(&hb_cpufreq_driver);
+ if (ret) {
+ pr_err("failed register driver: %d\n", ret);
+ goto out_free_table;
+ }
+
+ of_node_put(np);
+ return 0;
+
+out_free_table:
+ opp_free_cpufreq_table(cpu_dev, &freq_table);
+out_put_node:
+ of_node_put(np);
+ return ret;
+}
+late_initcall(hb_cpufreq_driver_init);
+
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>");
+MODULE_DESCRIPTION("Calxeda Highbank cpufreq driver");
+MODULE_LICENSE("GPL");
--
1.7.11.7
^ permalink raw reply related
* [PATCH 5/6 v6] power: export opp cpufreq functions
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel; +Cc: Mark Langsdorf
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf@calxeda.com>
These functions are needed to make the cpufreq-core0 and highbank-cpufreq
drivers loadable as modules.
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Acked-by: Nishanth Menon <nm@ti.com>
---
Changes from v4, v5
None.
Changes from v3
includes linux/export.h instead of module.h.
Changes from v2
None.
Changes from v1
Added Nishanth Menon's ack.
Clarified the purpose of the change in the commit message.
drivers/base/power/opp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index d946864..4062ec3 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -23,6 +23,7 @@
#include <linux/rcupdate.h>
#include <linux/opp.h>
#include <linux/of.h>
+#include <linux/export.h>
/*
* Internal data structure organization with the OPP layer library is as
@@ -643,6 +644,7 @@ int opp_init_cpufreq_table(struct device *dev,
return 0;
}
+EXPORT_SYMBOL(opp_init_cpufreq_table);
/**
* opp_free_cpufreq_table() - free the cpufreq table
@@ -660,6 +662,7 @@ void opp_free_cpufreq_table(struct device *dev,
kfree(*table);
*table = NULL;
}
+EXPORT_SYMBOL(opp_free_cpufreq_table);
#endif /* CONFIG_CPU_FREQ */
/**
@@ -720,4 +723,5 @@ int of_init_opp_table(struct device *dev)
return 0;
}
+EXPORT_SYMBOL(of_init_opp_table);
#endif
--
1.7.11.7
^ permalink raw reply related
* [PATCH 4/6 v6] arm highbank: add support for pl320 IPC
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel
Cc: Omar Ramirez Luna, Arnd Bergmann, Rob Herring, Mark Langsdorf
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf@calxeda.com>
From: Rob Herring <rob.herring@calxeda.com>
The pl320 IPC allows for interprocessor communication between the highbank A9
and the EnergyCore Management Engine. The pl320 implements a straightforward
mailbox protocol.
This patch depends on Omar Ramirez Luna's <omar.luna@linaro.org>
mailbox driver patch series.
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Omar Ramirez Luna <omar.luna@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
Changes from v5
Renamed ipc_transmit() to pl320_ipc_transmit().
Properly exported pl320_ipc_{un}register_notifier().
Changes from v4
Moved pl320-ipc.c from arch/arm/mach-highbank to drivers/mailbox.
Moved header information to include/linux/mailbox.h.
Added Kconfig options to reflect the new code location.
Change drivers/mailbox/Makefile to build the omap mailboxes only
when they are configured.
Removed ipc_call_fast and renamed ipc_call_slow ipc_transmit.
Changes from v3, v2
None.
Changes from v1
Removed erroneous changes for cpufreq Kconfig.
arch/arm/mach-highbank/Kconfig | 2 +
drivers/mailbox/Kconfig | 9 ++
drivers/mailbox/Makefile | 4 +
drivers/mailbox/pl320-ipc.c | 199 +++++++++++++++++++++++++++++++++++++++++
include/linux/mailbox.h | 19 +++-
5 files changed, 232 insertions(+), 1 deletion(-)
create mode 100644 drivers/mailbox/Makefile
create mode 100644 drivers/mailbox/pl320-ipc.c
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 0e1d0a4..2896881 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -11,5 +11,7 @@ config ARCH_HIGHBANK
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
select HAVE_SMP
+ select MAILBOX
+ select PL320_MBOX
select SPARSE_IRQ
select USE_OF
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index be8cac0..e89fdb4 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -34,4 +34,13 @@ config OMAP_MBOX_KFIFO_SIZE
This can also be changed at runtime (via the mbox_kfifo_size
module parameter).
+config PL320_MBOX
+ bool "ARM PL320 Mailbox"
+ help
+ An implementation of the ARM PL320 Interprocessor Communication
+ Mailbox (IPCM), tailored for the Calxeda Highbank. It is used to
+ send short messages between Highbank's A9 cores and the EnergyCore
+ Management Engine, primarily for cpufreq. Say Y here if you want
+ to use the PL320 IPCM support.
+
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
new file mode 100644
index 0000000..c9f14c3
--- /dev/null
+++ b/drivers/mailbox/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_OMAP1_MBOX) += mailbox.o mailbox-omap1.o
+obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox.o mailbox-omap2.o
+obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
+
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c
new file mode 100644
index 0000000..1a9d8e4
--- /dev/null
+++ b/drivers/mailbox/pl320-ipc.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+
+#include <linux/mailbox.h>
+
+#define IPCMxSOURCE(m) ((m) * 0x40)
+#define IPCMxDSET(m) (((m) * 0x40) + 0x004)
+#define IPCMxDCLEAR(m) (((m) * 0x40) + 0x008)
+#define IPCMxDSTATUS(m) (((m) * 0x40) + 0x00C)
+#define IPCMxMODE(m) (((m) * 0x40) + 0x010)
+#define IPCMxMSET(m) (((m) * 0x40) + 0x014)
+#define IPCMxMCLEAR(m) (((m) * 0x40) + 0x018)
+#define IPCMxMSTATUS(m) (((m) * 0x40) + 0x01C)
+#define IPCMxSEND(m) (((m) * 0x40) + 0x020)
+#define IPCMxDR(m, dr) (((m) * 0x40) + ((dr) * 4) + 0x024)
+
+#define IPCMMIS(irq) (((irq) * 8) + 0x800)
+#define IPCMRIS(irq) (((irq) * 8) + 0x804)
+
+#define MBOX_MASK(n) (1 << (n))
+#define IPC_TX_MBOX 1
+#define IPC_RX_MBOX 2
+
+#define CHAN_MASK(n) (1 << (n))
+#define A9_SOURCE 1
+#define M3_SOURCE 0
+
+static void __iomem *ipc_base;
+static int ipc_irq;
+static DEFINE_MUTEX(ipc_m1_lock);
+static DECLARE_COMPLETION(ipc_completion);
+static ATOMIC_NOTIFIER_HEAD(ipc_notifier);
+
+static inline void set_destination(int source, int mbox)
+{
+ __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox));
+ __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox));
+}
+
+static inline void clear_destination(int source, int mbox)
+{
+ __raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox));
+ __raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox));
+}
+
+static void __ipc_send(int mbox, u32 *data)
+{
+ int i;
+ for (i = 0; i < 7; i++)
+ __raw_writel(data[i], ipc_base + IPCMxDR(mbox, i));
+ __raw_writel(0x1, ipc_base + IPCMxSEND(mbox));
+}
+
+static u32 __ipc_rcv(int mbox, u32 *data)
+{
+ int i;
+ for (i = 0; i < 7; i++)
+ data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i));
+ return data[1];
+}
+
+/* blocking implmentation from the A9 side, not usuable in interrupts! */
+int pl320_ipc_transmit(u32 *data)
+{
+ int ret;
+
+ mutex_lock(&ipc_m1_lock);
+
+ init_completion(&ipc_completion);
+ __ipc_send(IPC_TX_MBOX, data);
+ ret = wait_for_completion_timeout(&ipc_completion,
+ msecs_to_jiffies(1000));
+ if (ret == 0) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ ret = __ipc_rcv(IPC_TX_MBOX, data);
+out:
+ mutex_unlock(&ipc_m1_lock);
+ return ret;
+}
+EXPORT_SYMBOL(pl320_ipc_transmit);
+
+irqreturn_t ipc_handler(int irq, void *dev)
+{
+ u32 irq_stat;
+ u32 data[7];
+
+ irq_stat = __raw_readl(ipc_base + IPCMMIS(1));
+ if (irq_stat & MBOX_MASK(IPC_TX_MBOX)) {
+ __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+ complete(&ipc_completion);
+ }
+ if (irq_stat & MBOX_MASK(IPC_RX_MBOX)) {
+ __ipc_rcv(IPC_RX_MBOX, data);
+ atomic_notifier_call_chain(&ipc_notifier, data[0], data + 1);
+ __raw_writel(2, ipc_base + IPCMxSEND(IPC_RX_MBOX));
+ }
+
+ return IRQ_HANDLED;
+}
+
+int pl320_ipc_register_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL(pl320_ipc_register_notifier);
+
+int pl320_ipc_unregister_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL(pl320_ipc_unregister_notifier);
+
+static int __devinit pl320_probe(struct amba_device *adev,
+ const struct amba_id *id)
+{
+ int ret;
+
+ ipc_base = ioremap(adev->res.start, resource_size(&adev->res));
+ if (ipc_base == NULL)
+ return -ENOMEM;
+
+ __raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+
+ ipc_irq = adev->irq[0];
+ ret = request_irq(ipc_irq, ipc_handler, 0, dev_name(&adev->dev), NULL);
+ if (ret < 0)
+ goto err;
+
+ /* Init slow mailbox */
+ __raw_writel(CHAN_MASK(A9_SOURCE),
+ ipc_base + IPCMxSOURCE(IPC_TX_MBOX));
+ __raw_writel(CHAN_MASK(M3_SOURCE),
+ ipc_base + IPCMxDSET(IPC_TX_MBOX));
+ __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+ ipc_base + IPCMxMSET(IPC_TX_MBOX));
+
+ /* Init receive mailbox */
+ __raw_writel(CHAN_MASK(M3_SOURCE),
+ ipc_base + IPCMxSOURCE(IPC_RX_MBOX));
+ __raw_writel(CHAN_MASK(A9_SOURCE),
+ ipc_base + IPCMxDSET(IPC_RX_MBOX));
+ __raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+ ipc_base + IPCMxMSET(IPC_RX_MBOX));
+
+ return 0;
+err:
+ iounmap(ipc_base);
+ return ret;
+}
+
+static struct amba_id pl320_ids[] = {
+ {
+ .id = 0x00041320,
+ .mask = 0x000fffff,
+ },
+ { 0, 0 },
+};
+
+static struct amba_driver pl320_driver = {
+ .drv = {
+ .name = "pl320",
+ },
+ .id_table = pl320_ids,
+ .probe = pl320_probe,
+};
+
+static int __init ipc_init(void)
+{
+ return amba_driver_register(&pl320_driver);
+}
+module_init(ipc_init);
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
index e8e4131..e7829e5 100644
--- a/include/linux/mailbox.h
+++ b/include/linux/mailbox.h
@@ -1,4 +1,16 @@
-/* mailbox.h */
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
typedef u32 mbox_msg_t;
struct omap_mbox;
@@ -20,3 +32,8 @@ void omap_mbox_save_ctx(struct omap_mbox *mbox);
void omap_mbox_restore_ctx(struct omap_mbox *mbox);
void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+
+int pl320_ipc_transmit(u32 *data);
+int pl320_ipc_register_notifier(struct notifier_block *nb);
+int pl320_ipc_unregister_notifier(struct notifier_block *nb);
+
--
1.7.11.7
^ permalink raw reply related
* [PATCH 3/6 v6] cpufreq: tolerate inexact values when collecting stats
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel; +Cc: Mark Langsdorf
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf@calxeda.com>
This patch is withdrawn due to a need for severe rework.
Changes from v4
Withdrawn.
Changes from v3, v2
None.
Changes from v1
Implemented a simple round-up algorithm instead of the over/under
method that could cause errors on Intel processors with boost mode.
^ permalink raw reply
* [PATCH 2/6 v6] clk, highbank: Prevent glitches in non-bypass reset mode
From: Mark Langsdorf @ 2012-11-27 20:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel
Cc: Mark Langsdorf, Rob Herring
In-Reply-To: <1354046672-7392-1-git-send-email-mark.langsdorf@calxeda.com>
The highbank clock will glitch with the current code if the
clock rate is reset without relocking the PLL. Program the PLL
correctly to prevent glitches.
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Mike Turquette <mturquette@linaro.org>
---
Changes from v5
Added Mike Turquette's ack.
Changes from v4
None.
Changes from v3
Changelog text and patch name now correspond to the actual patch.
was clk, highbank: remove non-bypass reset mode.
Changes from v2
None.
Changes from v1:
Removed erroneous reformating.
drivers/clk/clk-highbank.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index 52fecad..3a0b723 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
reg |= HB_PLL_EXT_ENA;
reg &= ~HB_PLL_EXT_BYPASS;
} else {
+ writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
reg &= ~HB_PLL_DIVQ_MASK;
reg |= divq << HB_PLL_DIVQ_SHIFT;
+ writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
}
writel(reg, hbclk->reg);
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH 4/6 v5] arm highbank: add support for pl320 IPC
From: Mark Langsdorf @ 2012-11-27 19:53 UTC (permalink / raw)
To: Thomas Petazzoni
Cc: linux-kernel@vger.kernel.org, cpufreq@vger.kernel.org,
linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Omar Ramirez Luna, Arnd Bergmann, Rob Herring
In-Reply-To: <20121127171250.3984e990@skate>
On 11/27/2012 10:12 AM, Thomas Petazzoni wrote:
> Dear Mark Langsdorf,
>
> On Tue, 27 Nov 2012 09:04:32 -0600, Mark Langsdorf wrote:
>
>> +int ipc_transmit(u32 *data);
>
> ipc_transmit() looks to me like a way to generic name to be exposed to
> the entire kernel.
Good point. Changed to pl320_ipc_transmit()
>> +extern int pl320_ipc_register_notifier(struct notifier_block *nb);
>> +extern int pl320_ipc_unregister_notifier(struct notifier_block *nb);
>
> Why some "extern" here? You don't have these for the other functions in
> this header file.
Nice catch. Fixed to export them in cpufreq.
--Mark Langsdorf
Calxeda, Inc.
^ permalink raw reply
* Re: [PATCH] cpuidle: Measure idle state durations with monotonic clock
From: Rafael J. Wysocki @ 2012-11-27 19:12 UTC (permalink / raw)
To: linux-pm
Cc: Julius Werner, linux-kernel, Len Brown, Kevin Hilman,
Andrew Morton, Srivatsa S. Bhat, linux-acpi, linuxppc-dev,
Deepthi Dharwar, Trinabh Gupta, Sameer Nanda, Lists Linaro-dev,
Daniel Lezcano
In-Reply-To: <1352944590-8776-1-git-send-email-jwerner@chromium.org>
On Wednesday, November 14, 2012 05:56:30 PM Julius Werner wrote:
> Many cpuidle drivers measure their time spent in an idle state by
> reading the wallclock time before and after idling and calculating the
> difference. This leads to erroneous results when the wallclock time gets
> updated by another processor in the meantime, adding that clock
> adjustment to the idle state's time counter.
>
> If the clock adjustment was negative, the result is even worse due to an
> erroneous cast from int to unsigned long long of the last_residency
> variable. The negative 32 bit integer will zero-extend and result in a
> forward time jump of roughly four billion milliseconds or 1.3 hours on
> the idle state residency counter.
>
> This patch changes all affected cpuidle drivers to either use the
> monotonic clock for their measurements or make use of the generic time
> measurement wrapper in cpuidle.c, which was already working correctly.
> Some superfluous CLIs/STIs in the ACPI code are removed (interrupts
> should always already be disabled before entering the idle function, and
> not get reenabled until the generic wrapper has performed its second
> measurement). It also removes the erroneous cast, making sure that
> negative residency values are applied correctly even though they should
> not appear anymore.
Applied to the linux-next branch of the linux-pm.git tree.
Thanks,
Rafael
> Signed-off-by: Julius Werner <jwerner@chromium.org>
> ---
> arch/powerpc/platforms/pseries/processor_idle.c | 4 +-
> drivers/acpi/processor_idle.c | 57 +---------------------
> drivers/cpuidle/cpuidle.c | 3 +-
> drivers/idle/intel_idle.c | 14 +-----
> 4 files changed, 7 insertions(+), 71 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
> index 45d00e5..4d806b4 100644
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ b/arch/powerpc/platforms/pseries/processor_idle.c
> @@ -36,7 +36,7 @@ static struct cpuidle_state *cpuidle_state_table;
> static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
> {
>
> - *kt_before = ktime_get_real();
> + *kt_before = ktime_get();
> *in_purr = mfspr(SPRN_PURR);
> /*
> * Indicate to the HV that we are idle. Now would be
> @@ -50,7 +50,7 @@ static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before)
> get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
> get_lppaca()->idle = 0;
>
> - return ktime_to_us(ktime_sub(ktime_get_real(), kt_before));
> + return ktime_to_us(ktime_sub(ktime_get(), kt_before));
> }
>
> static int snooze_loop(struct cpuidle_device *dev,
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index e8086c7..f1a5da4 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -735,31 +735,18 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
> static int acpi_idle_enter_c1(struct cpuidle_device *dev,
> struct cpuidle_driver *drv, int index)
> {
> - ktime_t kt1, kt2;
> - s64 idle_time;
> struct acpi_processor *pr;
> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
>
> pr = __this_cpu_read(processors);
> - dev->last_residency = 0;
>
> if (unlikely(!pr))
> return -EINVAL;
>
> - local_irq_disable();
> -
> -
> lapic_timer_state_broadcast(pr, cx, 1);
> - kt1 = ktime_get_real();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> - idle_time = ktime_to_us(ktime_sub(kt2, kt1));
> -
> - /* Update device last_residency*/
> - dev->last_residency = (int)idle_time;
>
> - local_irq_enable();
> lapic_timer_state_broadcast(pr, cx, 0);
>
> return index;
> @@ -806,19 +793,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
> struct acpi_processor *pr;
> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
> - ktime_t kt1, kt2;
> - s64 idle_time_ns;
> - s64 idle_time;
>
> pr = __this_cpu_read(processors);
> - dev->last_residency = 0;
>
> if (unlikely(!pr))
> return -EINVAL;
>
> - local_irq_disable();
> -
> -
> if (cx->entry_method != ACPI_CSTATE_FFH) {
> current_thread_info()->status &= ~TS_POLLING;
> /*
> @@ -829,7 +809,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
>
> if (unlikely(need_resched())) {
> current_thread_info()->status |= TS_POLLING;
> - local_irq_enable();
> return -EINVAL;
> }
> }
> @@ -843,22 +822,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
> if (cx->type == ACPI_STATE_C3)
> ACPI_FLUSH_CPU_CACHE();
>
> - kt1 = ktime_get_real();
> /* Tell the scheduler that we are going deep-idle: */
> sched_clock_idle_sleep_event();
> acpi_idle_do_entry(cx);
> - kt2 = ktime_get_real();
> - idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> - idle_time = idle_time_ns;
> - do_div(idle_time, NSEC_PER_USEC);
>
> - /* Update device last_residency*/
> - dev->last_residency = (int)idle_time;
> + sched_clock_idle_wakeup_event(0);
>
> - /* Tell the scheduler how much we idled: */
> - sched_clock_idle_wakeup_event(idle_time_ns);
> -
> - local_irq_enable();
> if (cx->entry_method != ACPI_CSTATE_FFH)
> current_thread_info()->status |= TS_POLLING;
>
> @@ -883,13 +852,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> struct acpi_processor *pr;
> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage);
> - ktime_t kt1, kt2;
> - s64 idle_time_ns;
> - s64 idle_time;
> -
>
> pr = __this_cpu_read(processors);
> - dev->last_residency = 0;
>
> if (unlikely(!pr))
> return -EINVAL;
> @@ -899,16 +863,11 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> return drv->states[drv->safe_state_index].enter(dev,
> drv, drv->safe_state_index);
> } else {
> - local_irq_disable();
> acpi_safe_halt();
> - local_irq_enable();
> return -EBUSY;
> }
> }
>
> - local_irq_disable();
> -
> -
> if (cx->entry_method != ACPI_CSTATE_FFH) {
> current_thread_info()->status &= ~TS_POLLING;
> /*
> @@ -919,7 +878,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
>
> if (unlikely(need_resched())) {
> current_thread_info()->status |= TS_POLLING;
> - local_irq_enable();
> return -EINVAL;
> }
> }
> @@ -934,7 +892,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> */
> lapic_timer_state_broadcast(pr, cx, 1);
>
> - kt1 = ktime_get_real();
> /*
> * disable bus master
> * bm_check implies we need ARB_DIS
> @@ -965,18 +922,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> c3_cpu_count--;
> raw_spin_unlock(&c3_lock);
> }
> - kt2 = ktime_get_real();
> - idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1));
> - idle_time = idle_time_ns;
> - do_div(idle_time, NSEC_PER_USEC);
> -
> - /* Update device last_residency*/
> - dev->last_residency = (int)idle_time;
>
> - /* Tell the scheduler how much we idled: */
> - sched_clock_idle_wakeup_event(idle_time_ns);
> + sched_clock_idle_wakeup_event(0);
>
> - local_irq_enable();
> if (cx->entry_method != ACPI_CSTATE_FFH)
> current_thread_info()->status |= TS_POLLING;
>
> @@ -987,6 +935,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
> struct cpuidle_driver acpi_idle_driver = {
> .name = "acpi_idle",
> .owner = THIS_MODULE,
> + .en_core_tk_irqen = 1,
> };
>
> /**
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 7f15b85..1536edd 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -109,8 +109,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
> /* This can be moved to within driver enter routine
> * but that results in multiple copies of same code.
> */
> - dev->states_usage[entered_state].time +=
> - (unsigned long long)dev->last_residency;
> + dev->states_usage[entered_state].time += dev->last_residency;
> dev->states_usage[entered_state].usage++;
> } else {
> dev->last_residency = 0;
> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
> index b0f6b4c..c49c04d 100644
> --- a/drivers/idle/intel_idle.c
> +++ b/drivers/idle/intel_idle.c
> @@ -56,7 +56,6 @@
> #include <linux/kernel.h>
> #include <linux/cpuidle.h>
> #include <linux/clockchips.h>
> -#include <linux/hrtimer.h> /* ktime_get_real() */
> #include <trace/events/power.h>
> #include <linux/sched.h>
> #include <linux/notifier.h>
> @@ -72,6 +71,7 @@
> static struct cpuidle_driver intel_idle_driver = {
> .name = "intel_idle",
> .owner = THIS_MODULE,
> + .en_core_tk_irqen = 1,
> };
> /* intel_idle.max_cstate=0 disables driver */
> static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1;
> @@ -281,8 +281,6 @@ static int intel_idle(struct cpuidle_device *dev,
> struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
> unsigned long eax = (unsigned long)cpuidle_get_statedata(state_usage);
> unsigned int cstate;
> - ktime_t kt_before, kt_after;
> - s64 usec_delta;
> int cpu = smp_processor_id();
>
> cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
> @@ -297,8 +295,6 @@ static int intel_idle(struct cpuidle_device *dev,
> if (!(lapic_timer_reliable_states & (1 << (cstate))))
> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
>
> - kt_before = ktime_get_real();
> -
> stop_critical_timings();
> if (!need_resched()) {
>
> @@ -310,17 +306,9 @@ static int intel_idle(struct cpuidle_device *dev,
>
> start_critical_timings();
>
> - kt_after = ktime_get_real();
> - usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before));
> -
> - local_irq_enable();
> -
> if (!(lapic_timer_reliable_states & (1 << (cstate))))
> clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
>
> - /* Update cpuidle counters */
> - dev->last_residency = (int)usec_delta;
> -
> return index;
> }
>
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH v2 3/3] PM: Introduce Intel PowerClamp Driver
From: Jacob Pan @ 2012-11-27 19:01 UTC (permalink / raw)
To: Joe Perches
Cc: Linux PM, LKML, Peter Zijlstra, Rafael Wysocki, Len Brown,
Thomas Gleixner, H. Peter Anvin, Ingo Molnar, Zhang Rui,
Rob Landley, Arjan van de Ven, Paul McKenney
In-Reply-To: <1353972445.2493.19.camel@joe-AO722>
On Mon, 26 Nov 2012 15:27:25 -0800
Joe Perches <joe@perches.com> wrote:
> On Mon, 2012-11-26 at 06:37 -0800, Jacob Pan wrote:
> > Intel PowerClamp driver performs synchronized idle injection across
> > all online CPUs. The goal is to maintain a given package level
> > C-state ratio.
>
> trivial notes:
>
> > diff --git a/drivers/thermal/intel_powerclamp.c
> > b/drivers/thermal/intel_powerclamp.c
>
> You should still add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> before any include so that all messages are prefixed with powerclamp:
>
I missed that. will fix in v4. thanks.
> > +
> > +/* #define DEBUG */
> > +
> > +#include <linux/module.h>
> > +#include <linux/kernel.h>
> []
> > +static void adjust_compensation(int target_ratio, unsigned int win)
> > +{
> > + int delta;
>
> It'd be shorter code to use a temporary like
>
> struct powerclamp_calibration_data *d =
> &cal_data[target_ratio];
>
> > +
> > + /*
> > + * adjust compensations if confidence level has not been
> > reached or
> > + * there are too many wakeups during the last idle
> > injection period, we
> > + * cannot trust the data for compensation.
> > + */
> > + if (cal_data[target_ratio].confidence >= CONFIDENCE_OK ||
> > + atomic_read(&idle_wakeup_counter) >
> > + win * num_online_cpus())
> > + return;
> > +
> > + delta = set_target_ratio - current_ratio;
> > + /* filter out bad data */
> > + if (delta >= 0 && delta <= (1+target_ratio/10)) {
> > + if (cal_data[target_ratio].steady_comp)
> > + cal_data[target_ratio].steady_comp =
> > + roundup(delta+
> > +
> > cal_data[target_ratio].steady_comp,
> > + 2)/2;
>
> so that this fits on a single line and becomes:
>
> if (d->steady_comp)
> d->steady_comp = roundup(delta +
> d->steady_comp, 2) / 2;
> etc.
>
looks much better, will fix.
> What clamps target_ratio to the correct range?
> I briefly scanned the code but didn't spot it.
>
target_ratio is a local variable for set_target_ratio, I did this to
avoid locking in case user wants to change it during computation.
set_target_ratio is clamped by:
if (set_target_ratio > MAX_TARGET_RATIO)
set_target_ratio = MAX_TARGET_RATIO;
I guess i could use clamp() macro.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[Jacob Pan]
--
Thanks,
Jacob
^ permalink raw reply
* Re: [PATCH] fixup! cpufreq: SPEAr: Add CPUFreq driver
From: Rafael J. Wysocki @ 2012-11-27 19:05 UTC (permalink / raw)
To: linux-pm
Cc: Viresh Kumar, spear-devel, devicetree-discuss, linux-arm-kernel,
cpufreq
In-Reply-To: <2d845c8e19392c2b82a243e6e878ae4e5e771c2f.1353785862.git.viresh.kumar@linaro.org>
On Tuesday, November 27, 2012 06:01:39 PM Viresh Kumar wrote:
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> Hi Rafael,
>
> To make review easier and faster, i am sending incremental patch for SPEAr
> cpufreq driver. This patch was earlier discussed here:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/135088.html
Applied.
Thanks,
Rafael
> .../devicetree/bindings/cpufreq/cpufreq-spear.txt | 33 +++++++++++++++-------
> drivers/cpufreq/spear-cpufreq.c | 4 +--
> 2 files changed, 25 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt
> index 4cf2819..f3d44984 100644
> --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-spear.txt
> @@ -6,7 +6,6 @@ It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) systems
> which share clock across all CPUs.
>
> Required properties:
> -- compatible: "st,cpufreq-spear"
> - cpufreq_tbl: Table of frequencies CPU could be transitioned into, in the
> increasing order.
>
> @@ -14,16 +13,30 @@ Optional properties:
> - clock-latency: Specify the possible maximum transition latency for clock, in
> unit of nanoseconds.
>
> +Both required and optional properties listed above must be defined under node
> +/cpus/cpu@0.
> +
> Examples:
> --------
> +cpus {
> +
> + <...>
> +
> + cpu@0 {
> + compatible = "arm,cortex-a9";
> + reg = <0>;
> +
> + <...>
> +
> + cpufreq_tbl = < 166000
> + 200000
> + 250000
> + 300000
> + 400000
> + 500000
> + 600000 >;
> + };
> +
> + <...>
>
> -cpufreq {
> - compatible = "st,cpufreq-spear";
> - cpufreq_tbl = < 166000
> - 200000
> - 250000
> - 300000
> - 400000
> - 500000
> - 600000 >;
> };
> diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
> index a7fe880..4575cfe 100644
> --- a/drivers/cpufreq/spear-cpufreq.c
> +++ b/drivers/cpufreq/spear-cpufreq.c
> @@ -224,9 +224,9 @@ static int spear_cpufreq_driver_init(void)
> const __be32 *val;
> int cnt, i, ret;
>
> - np = of_find_compatible_node(NULL, NULL, "st,cpufreq-spear");
> + np = of_find_node_by_path("/cpus/cpu@0");
> if (!np) {
> - pr_err("No cpufreq node found");
> + pr_err("No cpu node found");
> return -ENODEV;
> }
>
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH 0/6 v5] cpufreq: add support for Calxeda ECX-1000 (highbank)
From: Rafael J. Wysocki @ 2012-11-27 19:04 UTC (permalink / raw)
To: Mark Langsdorf
Cc: linux-pm, linux-kernel, cpufreq, linux-arm-kernel,
Thomas Petazzoni
In-Reply-To: <1354028674-23685-1-git-send-email-mark.langsdorf@calxeda.com>
On Tuesday, November 27, 2012 09:04:28 AM Mark Langsdorf wrote:
> This patch series adds cpufreq support for the Calxeda
> ECX-1000 (highbank) SoCs. The driver is based on the
> cpufreq-cpu0 driver. Because of the unique way that
> highbank uses the EnergyCore Management Engine to manage
> voltages, it was not possible to use the cpufreq-cpu0 driver.
Well, Thomas still seems to be unhappy with [4/6], although those don't seem
to be essential points.
Can you please address his comments?
I can't promise I'll take it to my first pull request during the upcoming merge
window, but it looks like there will be a second one anyway.
Thanks,
Rafael
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH 2/6 v5] clk, highbank: Prevent glitches in non-bypass reset mode
From: Mike Turquette @ 2012-11-27 18:15 UTC (permalink / raw)
To: Mark Langsdorf
Cc: linux-kernel, cpufreq, linux-pm@vger.kernel.org, linux-arm-kernel,
Rob Herring
In-Reply-To: <1354028674-23685-3-git-send-email-mark.langsdorf@calxeda.com>
On Tue, Nov 27, 2012 at 7:04 AM, Mark Langsdorf
<mark.langsdorf@calxeda.com> wrote:
>
> The highbank clock will glitch with the current code if the
> clock rate is reset without relocking the PLL. Program the PLL
> correctly to prevent glitches.
>
> Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: mturquette@linaro.org
Acked-by: Mike Turquette <mturquette@linaro.org>
Regards,
Mike
> ---
> Changes from v4
> None.
> Changes from v3
> Changelog text and patch name now correspond to the actual patch.
> was clk, highbank: remove non-bypass reset mode.
> Changes from v2
> None.
> Changes from v1:
> Removed erroneous reformating.
>
> drivers/clk/clk-highbank.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
> index 52fecad..3a0b723 100644
> --- a/drivers/clk/clk-highbank.c
> +++ b/drivers/clk/clk-highbank.c
> @@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
> reg |= HB_PLL_EXT_ENA;
> reg &= ~HB_PLL_EXT_BYPASS;
> } else {
> + writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
> reg &= ~HB_PLL_DIVQ_MASK;
> reg |= divq << HB_PLL_DIVQ_SHIFT;
> + writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
> }
> writel(reg, hbclk->reg);
>
> --
> 1.7.11.7
>
^ permalink raw reply
* Re: [PATCHv9 1/3] Runtime Interpreted Power Sequences
From: Mark Brown @ 2012-11-27 16:46 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Tomi Valkeinen, Thierry Reding, Tomi Valkeinen, Alex Courbot,
Grant Likely, Anton Vorontsov, Stephen Warren, Mark Zhang,
Rob Herring, David Woodhouse, Arnd Bergmann,
linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
devicetree-discuss@lists.ozlabs.org, linux-pm@vger.kernel.org,
Alexandre Courbot
In-Reply-To: <3136860.Z3VvKjeKpU@avalon>
[-- Attachment #1: Type: text/plain, Size: 808 bytes --]
On Tue, Nov 27, 2012 at 04:37:32PM +0100, Laurent Pinchart wrote:
> One possibly crazy idea I had was to replace backlight devices as we know them
> with LED devices (a LED driver IC shouldn't be supported by different APIs
> depending on whether the LEDs it drives are used as a backlight or not), and
> have the panel hook up with the associated LED device to expose backlight
> operations through the CDF. Panels with a backlight controller tied to the
> panel controller (control through DSI for instance) would implement the
> backlight operations directly without instantiating a LED device. This still
> leaves the question of the userspace backlight brightness API open.
I remember looking at that before but never actually got round to it, it
seems like a sensible idea to me.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 4/6 v5] arm highbank: add support for pl320 IPC
From: Thomas Petazzoni @ 2012-11-27 16:12 UTC (permalink / raw)
To: Mark Langsdorf
Cc: linux-kernel, cpufreq, linux-pm, linux-arm-kernel,
Omar Ramirez Luna, Arnd Bergmann, Rob Herring
In-Reply-To: <1354028674-23685-5-git-send-email-mark.langsdorf@calxeda.com>
Dear Mark Langsdorf,
On Tue, 27 Nov 2012 09:04:32 -0600, Mark Langsdorf wrote:
> +int ipc_transmit(u32 *data);
ipc_transmit() looks to me like a way to generic name to be exposed to
the entire kernel.
> +extern int pl320_ipc_register_notifier(struct notifier_block *nb);
> +extern int pl320_ipc_unregister_notifier(struct notifier_block *nb);
Why some "extern" here? You don't have these for the other functions in
this header file.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: [PATCHv9 1/3] Runtime Interpreted Power Sequences
From: Laurent Pinchart @ 2012-11-27 15:37 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Thierry Reding, Tomi Valkeinen, Alex Courbot, Grant Likely,
Anton Vorontsov, Stephen Warren, Mark Zhang, Rob Herring,
Mark Brown, David Woodhouse, Arnd Bergmann,
linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
devicetree-discuss@lists.ozlabs.org, linux-pm@vger.kernel.org,
Alexandre Courbot
In-Reply-To: <50B4D9E9.8070607@ti.com>
[-- Attachment #1: Type: text/plain, Size: 4870 bytes --]
Hi Tomi,
On Tuesday 27 November 2012 17:19:05 Tomi Valkeinen wrote:
> On 2012-11-27 17:08, Laurent Pinchart wrote:
> > On Wednesday 21 November 2012 14:04:17 Tomi Valkeinen wrote:
> >> On 2012-11-21 13:40, Thierry Reding wrote:
> > [snip]
> >
> >>> One thing that's not very clear is how the backlight subsystem should be
> >>> wired up with the display framework. I have a patch on top of the Tegra
> >>> DRM driver which adds some ad-hoc display support using this power
> >>> sequences series and the pwm-backlight.
> >>
> >> I think that's a separate issue: how to associate the lcd device and
> >> backlight device together. I don't have a clear answer to this.
> >>
> >> There are many ways the backlight may be handled. In some cases the
> >> panel and the backlight are truly independent, and you can use the other
> >> without using the other (not very practical, though =).
> >
> > From a control point of view that's always the case for DPI panels (as
> > those panels have no control bus, the backlight control bus is by
> > definition separate) and is the case for the two DBI panels I've seen
> > (but I won't claim that's a significative number of panels).
>
> They may have a control bus, I2C, SPI, etc. In some cases that can be
> used to control the backlight. But yes, it's separate from the video bus.
>
> >> But then with some LCDs the backlight may be controlled by sending
> >> commands to the panel, and in this case the two may be quite linked.
> >> Changing the backlight requires the panel driver to be up and running,
> >> and sometimes the sending the backlight commands may need to be (say, DSI
> >> display, with backlight commands going over the DSI bus).
> >
> > When you write "sending commands to the panel", do you mean on the same
> > control bus that the panel use ? Or would that also include for instance
> > an I2C backlight controller integrated inside a DSI panel module ? In the
> > later
>
> I mean the same control bus that is used to control the panel, be it shared
> with video bus like DSI, or separate like I2C.
>
> > case there might still be dependencies between the panel controller and
> > the backlight controller (let's say for instance that the panel controller
> > has a DSI-controller GPIO wired to the backlight controller reset signal),
> > but in practice I don't know if that's ever the case.
> >
> >> So my feeling is that the panel driver should know about the related
> >> backlight device. In the first case the panel driver would just call
> >> enable/disable in the backlight device when the panel is turned on.
> >
> > That makes sense. Unless I'm mistaken a backlight is always associated
> > with a panel (it would be called a light if there was no panel in front
> > of it). We can thus expose backlight operations in the panel CDF
> > (in-kernel) API. The panel driver would need a way to retrieve a pointer
> > to the associated backlight device.
>
> I agree.
>
> >> In the second case of the DSI panel... I'm not sure. I've implemented it
> >> so that the panel driver creates the backlight device, and implements
> >> the backlight callbacks. It then sends the DSI commands from those
> >> callbacks.
> >
> > If we decide to make the panel expose backlight operations we could get
> > rid of the backlight device in this case.
>
> Do you mean there would be a real backlight device only when there's a
> totally independent backlight for the panel?
I'm toying with that idea.
I see two reasons for having backlight devices in the kernel right now.
- Integration with the fbdev API to control the backlight automatically on
fbdev blank/unblank/suspend/resume. That's something I want to get rid of,
backlight should not depend on fbdev. If the backlight in-kernel API is
exposed by the panel through CDF operations we won't need this anymore.
- Exposing backlight control to userspace in sysfs. That's quite probably
something we want to keep, if only for compatibility reasons. Backlight on/off
should be controlled through the display APIs through DPMS control, but we
have no way that I'm aware of to control the backlight brightness in the FBDEV
and KMS APIs. It might make sense to add a backlight API to KMS for the
future.
One possibly crazy idea I had was to replace backlight devices as we know them
with LED devices (a LED driver IC shouldn't be supported by different APIs
depending on whether the LEDs it drives are used as a backlight or not), and
have the panel hook up with the associated LED device to expose backlight
operations through the CDF. Panels with a backlight controller tied to the
panel controller (control through DSI for instance) would implement the
backlight operations directly without instantiating a LED device. This still
leaves the question of the userspace backlight brightness API open.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [PATCHv9 1/3] Runtime Interpreted Power Sequences
From: Tomi Valkeinen @ 2012-11-27 15:19 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Alexandre Courbot,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Brown,
Stephen Warren, linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
Mark Zhang, Rob Herring,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Tomi Valkeinen, Anton Vorontsov,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
David Woodhouse,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <6982060.HfOokt4dIn@avalon>
[-- Attachment #1.1: Type: text/plain, Size: 3349 bytes --]
On 2012-11-27 17:08, Laurent Pinchart wrote:
> Hi Tomi,
>
> On Wednesday 21 November 2012 14:04:17 Tomi Valkeinen wrote:
>> On 2012-11-21 13:40, Thierry Reding wrote:
>
> [snip]
>
>>> One thing that's not very clear is how the backlight subsystem should be
>>> wired up with the display framework. I have a patch on top of the Tegra
>>> DRM driver which adds some ad-hoc display support using this power
>>> sequences series and the pwm-backlight.
>>
>> I think that's a separate issue: how to associate the lcd device and
>> backlight device together. I don't have a clear answer to this.
>>
>> There are many ways the backlight may be handled. In some cases the
>> panel and the backlight are truly independent, and you can use the other
>> without using the other (not very practical, though =).
>
> From a control point of view that's always the case for DPI panels (as those
> panels have no control bus, the backlight control bus is by definition
> separate) and is the case for the two DBI panels I've seen (but I won't claim
> that's a significative number of panels).
They may have a control bus, I2C, SPI, etc. In some cases that can be
used to control the backlight. But yes, it's separate from the video bus.
>> But then with some LCDs the backlight may be controlled by sending commands
>> to the panel, and in this case the two may be quite linked. Changing the
>> backlight requires the panel driver to be up and running, and sometimes the
>> sending the backlight commands may need to be (say, DSI display, with
>> backlight commands going over the DSI bus).
>
> When you write "sending commands to the panel", do you mean on the same
> control bus that the panel use ? Or would that also include for instance an
> I2C backlight controller integrated inside a DSI panel module ? In the later
I mean the same control bus that is used to control the panel, be it
shared with video bus like DSI, or separate like I2C.
> case there might still be dependencies between the panel controller and the
> backlight controller (let's say for instance that the panel controller has a
> DSI-controller GPIO wired to the backlight controller reset signal), but in
> practice I don't know if that's ever the case.
>
>> So my feeling is that the panel driver should know about the related
>> backlight device. In the first case the panel driver would just call
>> enable/disable in the backlight device when the panel is turned on.
>
> That makes sense. Unless I'm mistaken a backlight is always associated with a
> panel (it would be called a light if there was no panel in front of it). We
> can thus expose backlight operations in the panel CDF (in-kernel) API. The
> panel driver would need a way to retrieve a pointer to the associated
> backlight device.
I agree.
>> In the second case of the DSI panel... I'm not sure. I've implemented it
>> so that the panel driver creates the backlight device, and implements
>> the backlight callbacks. It then sends the DSI commands from those
>> callbacks.
>
> If we decide to make the panel expose backlight operations we could get rid of
> the backlight device in this case.
Do you mean there would be a real backlight device only when there's a
totally independent backlight for the panel?
Tomi
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 899 bytes --]
[-- Attachment #2: Type: text/plain, Size: 192 bytes --]
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply
* Re: [PATCHv9 1/3] Runtime Interpreted Power Sequences
From: Laurent Pinchart @ 2012-11-27 15:19 UTC (permalink / raw)
To: Thierry Reding
Cc: Tomi Valkeinen, Tomi Valkeinen, Alex Courbot, Grant Likely,
Anton Vorontsov, Stephen Warren, Mark Zhang, Rob Herring,
Mark Brown, David Woodhouse, Arnd Bergmann,
linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
devicetree-discuss@lists.ozlabs.org, linux-pm@vger.kernel.org,
Alexandre Courbot
In-Reply-To: <20121121130039.GA12191@avionic-0098.adnet.avionic-design.de>
[-- Attachment #1: Type: text/plain, Size: 8540 bytes --]
Hi Thierry,
On Wednesday 21 November 2012 14:00:39 Thierry Reding wrote:
> On Wed, Nov 21, 2012 at 02:04:17PM +0200, Tomi Valkeinen wrote:
> > On 2012-11-21 13:40, Thierry Reding wrote:
> > > On Wed, Nov 21, 2012 at 01:06:03PM +0200, Tomi Valkeinen wrote:
> > (sorry for bouncing back and forth with my private and my @ti addresses.
> > I can't find an option in thunderbird to only use one sender address,
> > and I always forget to change it when responding...)
> >
> > >> My suggestion would be to go forward with an in-driver solution, and
> > >> look at the DT based solution later if we are seeing an increasing
> > >> bloat in the drivers.
> > >
> > > Assuming we go with your approach, what's the plan? We're actually
> > > facing this problem right now for Tegra. Basically we have a DRM driver
> > > that can drive the panel, but we're still missing a way to hook up the
> > > backlight and panel enabling code. So we effectively can't support any
> > > of the LVDS devices out there without this series.
> >
> > Could you describe the hardware setup you have related to the LCD and
> > backlight? Is it a public board with public schematics?
>
> I don't think any of the schematics are public. The Tamonten Evaluation
> Carrier is available publicly from our website and the schematics are
> available on demand as well. If required I can probably arrange to send
> you a copy.
>
> > I've understood that you don't have anything special in your board, just
> > an LCD and a backlight, and the power sequences are related to powering
> > up the LCD and the backlight, without anything board specific. If so,
> > there's no need for board specific code, but just improving the panel
> > and backlight drivers to support the models you use.
>
> Correct. Basically we have two GPIOs that each enable the panel or the
> backlight respectively and one PWM to control the brightness. Are the
> panel drivers that you refer to those in drivers/video? I'm not sure if
> adding more ad-hoc drivers there just to move them to a generic
> framework in the next cycle is a good idea. I'd rather spend some time
> on helping to get the framework right and have drivers for that instead.
Thanks :-) It should be pretty easy to add support for an enable GPIO to the
DPI panel driver that I've posted as part of the CDF RFC v2.
> From what I understand by looking at the OMAP display drivers, they also
> provide the timings for the displays. Steffen's videomode helpers can be
> used to represent these easily in DT, but I suppose if all of those per-
> panel specifics are represented in the drivers then that won't be needed
> anymore either.
For DPI panels it might still make sense to provide the timings through DT or
platform data, as the driver might grow huge otherwise. Panel drivers that
support a couple (dozens) of different models could hardcode the timings.
> > > As I understand it, what you propose is similar to what ASoC does. For a
> > > specific board, you'd have to write a driver, presumably for the new
> > > panel/display framework, that provides code to power the panel on and
> > > off. That means we'll have to have a driver for each panel out there
> > > basically, or we'd need to write generic drivers that can be configured
> > > to some degree (via platform data or DT). This is similar to how ASoC
> > > works, where we have a driver that provides support for a specific codec
> > > connected to the Tegra SoC. For the display framework things could be
> > > done in a similar way I suppose, so that Tegra could have one display
> > > driver to handle all aspects of powering on and off the various panels
> > > for the various boards out there.
> >
> > I think we should only need the board drivers for very special cases. If
> > there's just a panel and a backlight, without any special dynamic muxing
> > or other trickery needed, I don't see a need for a board driver. I
> > presume this is the case for most of the boards.
>
> For Tegra ASoC, the way to provide for this is to allow a specific board
> to introduce a separate compatible value to enable per-board quirks or
> special handling if it cannot be supported by the generic driver and
> configuration mechanisms.
>
> > > Obviously, a lot of the code will be similar for other SoCs, but maybe
> > > that's just the way things are if we choose that approach. There's also
> > > the potential for factoring out large chunks of common code later on
> > > once we start to see common patterns.
> > >
> > > One thing that's not very clear is how the backlight subsystem should be
> > > wired up with the display framework. I have a patch on top of the Tegra
> > > DRM driver which adds some ad-hoc display support using this power
> > > sequences series and the pwm-backlight.
> >
> > I think that's a separate issue: how to associate the lcd device and
> > backlight device together. I don't have a clear answer to this.
> >
> > There are many ways the backlight may be handled. In some cases the
> > panel and the backlight are truly independent, and you can use the other
> > without using the other (not very practical, though =).
>
> At least for DT I think we can easily wire that up. I've actually posted
> a patch recently that does so. I think in most cases it makes sense to
> control them together, such as on DPMS changes, where you really want to
> turn both the backlight and the LCD off, independent of how they are
> tied together.
>
> > But then with some LCDs the backlight may be controlled by sending
> > commands to the panel, and in this case the two may be quite linked.
> > Changing the backlight requires the panel driver to be up and running,
> > and sometimes the sending the backlight commands may need to be (say,
> > DSI display, with backlight commands going over the DSI bus).
> >
> > So my feeling is that the panel driver should know about the related
> > backlight device. In the first case the panel driver would just call
> > enable/disable in the backlight device when the panel is turned on.
>
> Exactly.
>
> > In the second case of the DSI panel... I'm not sure. I've implemented it
> > so that the panel driver creates the backlight device, and implements
> > the backlight callbacks. It then sends the DSI commands from those
> > callbacks.
>
> That certainly sounds like the right approach to me.
>
> > > From reading the proposal for the panel/display framework, it sounds
> > > like a lot more is planned than just enabling or disabling panels, but
> > > it also seems like a lot of code needs to be written to support things
> > > like DSI, DBI or other control busses.
> > >
> > > At least for Tegra, and I think the same holds for a wide variety of
> > > other SoCs, dumb panels would be enough for a start. In the interest of
> > > getting a working solution for those setups, maybe we can start small
> > > and add just enough framework to register dumb panel drivers to along
> > > with code to wire up a backlight to light up the display. Then we could
> > > possibly still make it to have a proper solution to support the various
> > > LVDS panels for Tegra with 3.9.
> >
> > Yes, we (Laurent and me) both agree that we should start simple.
> >
> > However, the common panel framework is not strictly needed for this. I'm
> > not sure of the current architecture for Tegra, but for OMAP we already
> > have panel drivers (omap specific ones, though). The panel drivers may
> > support multiple models, (for example,
> > drivers/video/omap2/displays/panel-generic-dpi.c).
> >
> > I don't see any problem with adding small Tegra specific panel drivers
> > for the time being, with the intention of converting to common panel
> > framework when that's available.
>
> I can take a look at how such a driver could be implemented, but again,
> I'm a bit reluctant to add something ad-hoc now when maybe we can have
> it supported in a proper framework not too far away in the future.
>
> > Of course, the DT side is an issue. If you now create DT bindings for a
> > temporary model, and need to change it again later, you'll have some
> > headaches trying managing that without breaking the old bindings... This
> > is why I haven't pushed DT bindings for OMAP, as I know I have to change
> > them in the near future.
>
> We're already keeping back on this and none of the patches that define
> the bindings have been merged yet. Although bindings have been known to
> change every once in a while even for code that is already in mainline.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [PATCHv9 1/3] Runtime Interpreted Power Sequences
From: Laurent Pinchart @ 2012-11-27 15:08 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Thierry Reding, Tomi Valkeinen, Alex Courbot, Grant Likely,
Anton Vorontsov, Stephen Warren, Mark Zhang, Rob Herring,
Mark Brown, David Woodhouse, Arnd Bergmann,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Alexandre Courbot
In-Reply-To: <50ACC341.3090204-l0cyMroinI0@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 4498 bytes --]
Hi Tomi,
On Wednesday 21 November 2012 14:04:17 Tomi Valkeinen wrote:
> On 2012-11-21 13:40, Thierry Reding wrote:
[snip]
> > One thing that's not very clear is how the backlight subsystem should be
> > wired up with the display framework. I have a patch on top of the Tegra
> > DRM driver which adds some ad-hoc display support using this power
> > sequences series and the pwm-backlight.
>
> I think that's a separate issue: how to associate the lcd device and
> backlight device together. I don't have a clear answer to this.
>
> There are many ways the backlight may be handled. In some cases the
> panel and the backlight are truly independent, and you can use the other
> without using the other (not very practical, though =).
>From a control point of view that's always the case for DPI panels (as those
panels have no control bus, the backlight control bus is by definition
separate) and is the case for the two DBI panels I've seen (but I won't claim
that's a significative number of panels).
> But then with some LCDs the backlight may be controlled by sending commands
> to the panel, and in this case the two may be quite linked. Changing the
> backlight requires the panel driver to be up and running, and sometimes the
> sending the backlight commands may need to be (say, DSI display, with
> backlight commands going over the DSI bus).
When you write "sending commands to the panel", do you mean on the same
control bus that the panel use ? Or would that also include for instance an
I2C backlight controller integrated inside a DSI panel module ? In the later
case there might still be dependencies between the panel controller and the
backlight controller (let's say for instance that the panel controller has a
DSI-controller GPIO wired to the backlight controller reset signal), but in
practice I don't know if that's ever the case.
> So my feeling is that the panel driver should know about the related
> backlight device. In the first case the panel driver would just call
> enable/disable in the backlight device when the panel is turned on.
That makes sense. Unless I'm mistaken a backlight is always associated with a
panel (it would be called a light if there was no panel in front of it). We
can thus expose backlight operations in the panel CDF (in-kernel) API. The
panel driver would need a way to retrieve a pointer to the associated
backlight device.
> In the second case of the DSI panel... I'm not sure. I've implemented it
> so that the panel driver creates the backlight device, and implements
> the backlight callbacks. It then sends the DSI commands from those
> callbacks.
If we decide to make the panel expose backlight operations we could get rid of
the backlight device in this case.
> > From reading the proposal for the panel/display framework, it sounds
> > like a lot more is planned than just enabling or disabling panels, but
> > it also seems like a lot of code needs to be written to support things
> > like DSI, DBI or other control busses.
> >
> > At least for Tegra, and I think the same holds for a wide variety of
> > other SoCs, dumb panels would be enough for a start. In the interest of
> > getting a working solution for those setups, maybe we can start small
> > and add just enough framework to register dumb panel drivers to along
> > with code to wire up a backlight to light up the display. Then we could
> > possibly still make it to have a proper solution to support the various
> > LVDS panels for Tegra with 3.9.
>
> Yes, we (Laurent and me) both agree that we should start simple.
>
> However, the common panel framework is not strictly needed for this. I'm
> not sure of the current architecture for Tegra, but for OMAP we already
> have panel drivers (omap specific ones, though). The panel drivers may
> support multiple models, (for example,
> drivers/video/omap2/displays/panel-generic-dpi.c).
>
> I don't see any problem with adding small Tegra specific panel drivers
> for the time being, with the intention of converting to common panel
> framework when that's available.
I'm fine with that, but using the CDF would be even better :-)
> Of course, the DT side is an issue. If you now create DT bindings for a
> temporary model, and need to change it again later, you'll have some
> headaches trying managing that without breaking the old bindings... This
> is why I haven't pushed DT bindings for OMAP, as I know I have to change
> them in the near future.
--
Regards,
Laurent Pinchart
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* [PATCH 3/6 v5] cpufreq: tolerate inexact values when collecting stats
From: Mark Langsdorf @ 2012-11-27 15:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel; +Cc: Mark Langsdorf
In-Reply-To: <1354028674-23685-1-git-send-email-mark.langsdorf@calxeda.com>
This patch is withdrawn due to a need for severe rework.
Changes from v4
Withdrawn.
Changes from v3, v2
None.
Changes from v1
Implemented a simple round-up algorithm instead of the over/under
method that could cause errors on Intel processors with boost mode.
^ permalink raw reply
* [PATCH 0/6 v5] cpufreq: add support for Calxeda ECX-1000 (highbank)
From: Mark Langsdorf @ 2012-11-27 15:04 UTC (permalink / raw)
To: linux-kernel, cpufreq, linux-pm, linux-arm-kernel
In-Reply-To: <1351631056-25938-1-git-send-email-mark.langsdorf@calxeda.com>
This patch series adds cpufreq support for the Calxeda
ECX-1000 (highbank) SoCs. The driver is based on the
cpufreq-cpu0 driver. Because of the unique way that
highbank uses the EnergyCore Management Engine to manage
voltages, it was not possible to use the cpufreq-cpu0 driver.
--Mark Langsdorf
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox