* [PATCH 5/5] drm/sun4i: Add support for the overscan profiles
From: Maxime Ripard @ 2016-11-21 7:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161111091755.tfqizju5voazjrmm@phenom.ffwll.local>
On Fri, Nov 11, 2016 at 10:17:55AM +0100, Daniel Vetter wrote:
> On Thu, Nov 10, 2016 at 03:56:30PM +0100, Maxime Ripard wrote:
> > Hi Daniel,
> >
> > On Tue, Nov 08, 2016 at 09:59:27AM +0100, Daniel Vetter wrote:
> > > On Tue, Oct 18, 2016 at 10:29:38AM +0200, Maxime Ripard wrote:
> > > > Create overscan profiles reducing the displayed zone.
> > > >
> > > > For each TV standard (PAL and NTSC so far), we create 4 more reduced modes
> > > > by steps of 5% that the user will be able to select.
> > > >
> > > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > >
> > > tbh I think if we agree to do this (and that still seems an open question)
> > > I think there should be a generic helper to add these overscan modes with
> > > increased porches. Anything that only depends upon the sink (and
> > > overscanning is something the sink does) should imo be put into a suitable
> > > helper library for everyone to share.
> > >
> > > Or maybe even stash it into the probe helpers and call it for all TV
> > > connectors. Definitely not a driver-private thing.
> >
> > Last time we discussed it, my recollection was that you didn't want to
> > have generic code for it, but I'd be happy to implement it.
> >
> > I'll come up with something like that.
>
> Well I can flip-flop around with the nonsense I'm sometimes emitting ;-)
> Since you called me out, feel free to do whatever you want ...
I also found the generic solution to be a much better solution, so
I'll definitely implement it :)
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/7da26be6/attachment-0001.sig>
^ permalink raw reply
* [PATCH v16 05/15] clocksource/drivers/arm_arch_timer: fix a bug in arch_timer_register about arch_timer_uses_ppi
From: Fu Wei @ 2016-11-21 7:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118185252.GI1197@leverpostej>
Hi Mark,
On 19 November 2016 at 02:52, Mark Rutland <mark.rutland@arm.com> wrote:
> On Wed, Nov 16, 2016 at 09:48:58PM +0800, fu.wei at linaro.org wrote:
>> From: Fu Wei <fu.wei@linaro.org>
>>
>> The patch fix a potential bug about arch_timer_uses_ppi in
>> arch_timer_register.
>> On ARM64, we don't use ARCH_TIMER_PHYS_SECURE_PPI in Linux, so we will
>> just igorne it in init code.
>
> That's not currently the case. I assume you mean we will in later
> patches? If so, please make that clear in the commit message.
>
>> If arch_timer_uses_ppi is ARCH_TIMER_PHYS_NONSECURE_PPI, the orignal
>> code of arch_timer_uses_ppi may go wrong.
>
> How? What specifically happens?
>
> We don't currently assign ARCH_TIMER_PHYS_NONSECURE_PPI to
> arch_timer_uses_ppi, so I assume a later patch changes this. This change
> should be folded into said patch; it doesn't make sense in isolation.
yes, this patch is a preparation for the next which may set
arch_timer_use_ppi as ARCH_TIMER_PHYS_NONSECURE_PPI.
So you are right, I will merge this into the next and mention this
change in the commit message.
Great thanks
>
> Thanks,
> Mark.
>
>> Signed-off-by: Fu Wei <fu.wei@linaro.org>
>> ---
>> drivers/clocksource/arm_arch_timer.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
>> index dd1040d..6de164f 100644
>> --- a/drivers/clocksource/arm_arch_timer.c
>> +++ b/drivers/clocksource/arm_arch_timer.c
>> @@ -699,7 +699,7 @@ static int __init arch_timer_register(void)
>> case ARCH_TIMER_PHYS_NONSECURE_PPI:
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> - if (!err && arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]) {
>> + if (!err && arch_timer_has_nonsecure_ppi()) {
>> ppi = arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI];
>> err = request_percpu_irq(ppi, arch_timer_handler_phys,
>> "arch_timer", arch_timer_evt);
>> --
>> 2.7.4
>>
--
Best regards,
Fu Wei
Software Engineer
Red Hat
^ permalink raw reply
* [PATCH 1/5] drm/modes: Rewrite the command line parser
From: Maxime Ripard @ 2016-11-21 7:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vbKf3B2DYJA-kpmxa7vLzRcv5LhyVtToPyB2d6-thdt4Ng@mail.gmail.com>
Hi Sean,
Thanks for taking the time to review this.
On Wed, Nov 16, 2016 at 12:12:53PM -0500, Sean Paul wrote:
> On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > Rewrite the command line parser in order to get away from the state machine
> > parsing the video mode lines.
> >
> > Hopefully, this will allow to extend it more easily to support named modes
> > and / or properties set directly on the command line.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > drivers/gpu/drm/drm_modes.c | 305 +++++++++++++++++++++++--------------
> > 1 file changed, 190 insertions(+), 115 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> > index 53f07ac7c174..7d5bdca276f2 100644
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -30,6 +30,7 @@
> > * authorization from the copyright holder(s) and author(s).
> > */
> >
> > +#include <linux/ctype.h>
> > #include <linux/list.h>
> > #include <linux/list_sort.h>
> > #include <linux/export.h>
> > @@ -1261,6 +1262,131 @@ void drm_mode_connector_list_update(struct drm_connector *connector)
> > }
> > EXPORT_SYMBOL(drm_mode_connector_list_update);
> >
> > +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + if (str[0] != '-')
> > + return -EINVAL;
> > +
> > + mode->bpp = simple_strtol(str + 1, end_ptr, 10);
> > + mode->bpp_specified = true;
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + if (str[0] != '@')
> > + return -EINVAL;
> > +
> > + mode->refresh = simple_strtol(str + 1, end_ptr, 10);
> > + mode->refresh_specified = true;
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_extra(const char *str, int length,
> > + struct drm_connector *connector,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < length; i++) {
> > + switch (str[i]) {
> > + case 'i':
> > + mode->interlace = true;
> > + break;
> > + case 'm':
> > + mode->margins = true;
> > + break;
> > + case 'D':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
> > + (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
> > + mode->force = DRM_FORCE_ON;
> > + else
> > + mode->force = DRM_FORCE_ON_DIGITAL;
> > + break;
> > + case 'd':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + mode->force = DRM_FORCE_OFF;
> > + break;
> > + case 'e':
> > + if (mode->force != DRM_FORCE_UNSPECIFIED)
> > + return -EINVAL;
> > +
> > + mode->force = DRM_FORCE_ON;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
> > + bool extras,
> > + struct drm_connector *connector,
> > + struct drm_cmdline_mode *mode)
> > +{
> > + bool rb = false, cvt = false;
> > + int xres = 0, yres = 0;
> > + int remaining, i;
> > + char *end_ptr;
> > +
> > + xres = simple_strtol(str, &end_ptr, 10);
> > +
>
> checkpatch is telling me to use kstrtol instead, as simple_strtol is deprecated
>
> > + if (end_ptr[0] != 'x')
>
> check that end_ptr != NULL? you should probably also check that xres
> isn't an error (ie: -ERANGE or -EINVAL)
>
> > + return -EINVAL;
> > + end_ptr++;
> > +
> > + yres = simple_strtol(end_ptr, &end_ptr, 10);
>
> check end_ptr != NULL and yres sane
>
> > +
> > + remaining = length - (end_ptr - str);
> > + if (remaining < 0)
>
> right, so if end_ptr is NULL here, we'll end up with a huge positive
> value for remaining :)
>
> > + return -EINVAL;
> > +
> > + for (i = 0; i < remaining; i++) {
> > + switch (end_ptr[i]) {
> > + case 'M':
> > + cvt = true;
>
> the previous code ensured proper ordering as well as parsing, whereas
> yours will take these in any order (and accepts duplicates). i don't
> think this should cause any issues, but perhaps something to verify.
Yes, I definitely overlooked the order of the parameters (and now I
get why the switch was so convoluted...)
I'll come up with a second version fixing that (and the other comments
you had).
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/2a06cc04/attachment.sig>
^ permalink raw reply
* [PATCH 2/5] drm/modes: Support modes names on the command line
From: Maxime Ripard @ 2016-11-21 7:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOw6vb+bpf_JoPR8To0Q5Sfidxs=FTif0d3gpgCtFTOKnGCqfA@mail.gmail.com>
Hi Sean,
On Wed, Nov 16, 2016 at 12:21:42PM -0500, Sean Paul wrote:
> On Tue, Oct 18, 2016 at 4:29 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > The drm subsystem also uses the video= kernel parameter, and in the
> > documentation refers to the fbdev documentation for that parameter.
> >
> > However, that documentation also says that instead of giving the mode using
> > its resolution we can also give a name. However, DRM doesn't handle that
> > case at the moment. Even though in most case it shouldn't make any
> > difference, it might be useful for analog modes, where different standards
> > might have the same resolution, but still have a few different parameters
> > that are not encoded in the modes (NTSC vs NTSC-J vs PAL-M for example).
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > drivers/gpu/drm/drm_connector.c | 3 +-
> > drivers/gpu/drm/drm_fb_helper.c | 4 +++-
> > drivers/gpu/drm/drm_modes.c | 49 +++++++++++++++++++++++-----------
> > include/drm/drm_connector.h | 1 +-
> > 4 files changed, 41 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 2db7fb510b6c..27a8a511257c 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -147,8 +147,9 @@ static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
> > connector->force = mode->force;
> > }
> >
> > - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
> > + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n",
> > connector->name,
> > + mode->name ? mode->name : "",
> > mode->xres, mode->yres,
> > mode->refresh_specified ? mode->refresh : 60,
> > mode->rb ? " reduced blanking" : "",
> > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> > index 03414bde1f15..20a68305fb45 100644
> > --- a/drivers/gpu/drm/drm_fb_helper.c
> > +++ b/drivers/gpu/drm/drm_fb_helper.c
> > @@ -1748,6 +1748,10 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
> > prefer_non_interlace = !cmdline_mode->interlace;
> > again:
> > list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
> > + /* Check (optional) mode name first */
> > + if (!strcmp(mode->name, cmdline_mode->name))
> > + return mode;
> > +
> > /* check width/height */
> > if (mode->hdisplay != cmdline_mode->xres ||
> > mode->vdisplay != cmdline_mode->yres)
> > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> > index 7d5bdca276f2..fdbf541a5978 100644
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -1413,7 +1413,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > struct drm_cmdline_mode *mode)
> > {
> > const char *name;
> > - bool parse_extras = false;
> > + bool named_mode = false, parse_extras = false;
> > unsigned int bpp_off = 0, refresh_off = 0;
> > unsigned int mode_end = 0;
> > char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
> > @@ -1432,8 +1432,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> >
> > name = mode_option;
> >
> > + /*
> > + * If the first character is not a digit, then it means that
> > + * we have a named mode.
> > + */
> > if (!isdigit(name[0]))
> > - return false;
> > + named_mode = true;
> > + else
> > + named_mode = false;
>
> named_mode = isalpha(name[0]); might be more succinct (and covers
> special characters).
>
> >
> > /* Try to locate the bpp and refresh specifiers, if any */
> > bpp_ptr = strchr(name, '-');
> > @@ -1460,12 +1466,16 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > parse_extras = true;
> > }
> >
> > - ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
> > - parse_extras,
> > - connector,
> > - mode);
> > - if (ret)
> > - return false;
> > + if (named_mode) {
> > + strncpy(mode->name, name, mode_end);
> > + } else {
> > + ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
> > + parse_extras,
> > + connector,
> > + mode);
> > + if (ret)
> > + return false;
> > + }
> > mode->specified = true;
> >
> > if (bpp_ptr) {
> > @@ -1493,14 +1503,23 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> > extra_ptr = refresh_end_ptr;
> >
> > if (extra_ptr) {
> > - int remaining = strlen(name) - (extra_ptr - name);
> > + if (!named_mode) {
> > + int len = strlen(name) - (extra_ptr - name);
> >
> > - /*
> > - * We still have characters to process, while
> > - * we shouldn't have any
> > - */
> > - if (remaining > 0)
> > - return false;
> > + ret = drm_mode_parse_cmdline_extra(extra_ptr, len,
> > + connector, mode);
> > + if (ret)
> > + return false;
> > + } else {
> > + int remaining = strlen(name) - (extra_ptr - name);
> > +
> > + /*
> > + * We still have characters to process, while
> > + * we shouldn't have any
> > + */
> > + if (remaining > 0)
> > + return false;
>
> Correct me if I'm wrong, but this shouldn't ever happen. AFAICT, the
> only way it could would be if we parsed bpp or refresh in the named
> mode (since those are the only cases where we don't copy the whole
> string over). Shouldn't that be invalid anyways?
It's supposed to be supported by the video
string. Documentation/fb/modedb.txt defines:
Valid mode specifiers (mode_option argument):
<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
<name>[-<bpp>][@<refresh>]
So we can't just copy the string over, and we need to parse it :/
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/e27ca461/attachment.sig>
^ permalink raw reply
* [PATCH V9 0/6] Integration of function trace with System Trace IP blocks
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
IP blocks allowing a variety of trace sources to log debugging
information to a pre-defined area have been introduced on a couple of
architecture [1][2]. These system trace blocks (also known as STM)
typically follow the MIPI STPv2 protocol [3] and provide a system wide
logging facility to any device, running a kernel or not, with access
to the block's log entry port(s). Since each trace message has a
timestamp, it is possible to correlate events happening in the entire
system rather than being confined to the logging facility of a single
entity.
This patchset is trying to use STM IP blocks to store function tracing
information produced by Ftrace and I'm taking the Function trace
(trace type is TRACE_FN) as the example in this patchset, but other
types of traces also can be supported.
Logging information generated by the Ftrace subsystem to STM and gathered
in the sink device can be used in conjunction with trace data from other
board components, also collected in the same trace sink.
This example is using ARM coresight STM but the same would apply to any
other architecture wishing to do the same.
[1]. https://lwn.net/Articles/674746/
[2]. http://lxr.free-electrons.com/source/drivers/hwtracing/intel_th/
[3]. http://mipi.org/specifications/debug#STP
Changes from v8:
* Split the last patch into 4 according to the suggestion from Alexander Shishkin;
* Add Alexander Shishkin's Acked-by.
Changes from v7:
* Addressed comments from Steven Rostedt:
- Removed unnessecery code;
- Shrinked the dependence of 'STM_SOURCE_FTRACE' from 'TRACING' to 'FUNCTION_TRACER';
- Changed the parameter type from char* to void*, that makes more sense.
Changes from v6:
* Rebased on v4.9-rc1;
* Removed unused the declaration and header file including from trace.h
which was added in patch 1 of this series;
* Revised a bit the comments in trace.h .
Changes from v5:
* Addressed comments from Steven Rostedt:
- Removed .commit() from trace_export;
- Changed to directly call trace_process_export() instead of trace_export::commit();
- Used 'ring_buffer_event_length(event)' instead to get the trace size;
- Removed trace_export pointer from trace_array structure.
* Revised commit message a little to make the description more accurate.
Changes from v4:
* Addressed comments from Steven Rostedt:
- Removed 'inline' annotations from the function which is called via function pointer;
- Removed useless components from structure trace_export;
- Added '__rcu' annotation to the RCU variables;
- Used 'rcu_assign_pointer' to do every RCU assignment;
- Added WARN_ON_ONCE() when the .write() is not assigned;
- In order to reduce the overhead caused by adding this feature, this revision used an
global array instead of a big "if statement" to get the size of trace entry according
to the trace type.
- In order to keep the current logic unchanged, made ftrace_exports() only being called if
there's something have been added, i.e. if trace_export to stm_ftrace has been added in
this patchset.
Changes from v3:
* Addressed comments from Steven Rostedt:
- Added comments for the element 'name' and 'next' of trace_export;
- Changed to use RCU functions instead of mutex in function callback;
- Moved the check for name to register trace_export function;
* Renamed 'trace_function_exports' to 'trace_exports' since its
implementation is not only for function_trace; The similar changes on
'add_trace_export' and 'rm_trace_export'.
Changes from v2:
* Rebased on v4.8-rc1.
* Added trace_export class, and make traces can be exported to not only
ring buffer but also other area such as STM.
* Made stm_ftrace as an trace_export.
* More detailed changes are described in change log of each patch.
Changes from v1:
* Addressed comments from Alexander Shishkin:
- Modified some ambiguous change logs.
- Decoupled stm_ftrace and trace_output interface to STM.
- Changed the file name from stm_ftrace.c to stm/ftrace.c.
- Implemented link/unlink hooks for stm_ftrace.
* Removed useless header file include from stm/ftrace.c
* Added Acked-by from Steven Rostedt on 4/4.
Chunyan Zhang (6):
tracing: add a possibility of exporting function trace to other places
instead of ring buffer only
stm class: ftrace: Add ftrace-export-over-stm driver
coresight: Mark stm_generic_packet() with notrace
intel_th: Mark sth_stm_packet() with notrace
stm dummy: Mark dummy_stm_packet() with notrace
stm: Mark the functions of writing STM with notrace
drivers/hwtracing/coresight/coresight-stm.c | 2 +-
drivers/hwtracing/intel_th/sth.c | 11 ++-
drivers/hwtracing/stm/Kconfig | 11 +++
drivers/hwtracing/stm/Makefile | 2 +
drivers/hwtracing/stm/core.c | 7 +-
drivers/hwtracing/stm/dummy_stm.c | 2 +-
drivers/hwtracing/stm/ftrace.c | 87 +++++++++++++++++++
include/linux/stm.h | 4 +-
include/linux/trace.h | 28 ++++++
kernel/trace/trace.c | 129 +++++++++++++++++++++++++++-
10 files changed, 271 insertions(+), 12 deletions(-)
create mode 100644 drivers/hwtracing/stm/ftrace.c
create mode 100644 include/linux/trace.h
--
2.7.4
^ permalink raw reply
* [PATCH V9 1/6] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
Currently Function traces can be only exported to ring buffer, this
patch added trace_export concept which can process traces and export
them to a registered destination as an addition to the current only
one output of Ftrace - i.e. ring buffer.
In this way, if we want Function traces to be sent to other destination
rather than ring buffer only, we just need to register a new trace_export
and implement its own .write() function for writing traces to storage.
With this patch, only Function trace (trace type is TRACE_FN)
is supported.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
include/linux/trace.h | 28 +++++++++++
kernel/trace/trace.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 156 insertions(+), 1 deletion(-)
create mode 100644 include/linux/trace.h
diff --git a/include/linux/trace.h b/include/linux/trace.h
new file mode 100644
index 0000000..9330a58
--- /dev/null
+++ b/include/linux/trace.h
@@ -0,0 +1,28 @@
+#ifndef _LINUX_TRACE_H
+#define _LINUX_TRACE_H
+
+#ifdef CONFIG_TRACING
+/*
+ * The trace export - an export of Ftrace output. The trace_export
+ * can process traces and export them to a registered destination as
+ * an addition to the current only output of Ftrace - i.e. ring buffer.
+ *
+ * If you want traces to be sent to some other place rather than ring
+ * buffer only, just need to register a new trace_export and implement
+ * its own .write() function for writing traces to the storage.
+ *
+ * next - pointer to the next trace_export
+ * write - copy traces which have been delt with ->commit() to
+ * the destination
+ */
+struct trace_export {
+ struct trace_export __rcu *next;
+ void (*write)(const void *, unsigned int);
+};
+
+int register_ftrace_export(struct trace_export *export);
+int unregister_ftrace_export(struct trace_export *export);
+
+#endif /* CONFIG_TRACING */
+
+#endif /* _LINUX_TRACE_H */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8696ce6..038291d 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -40,6 +40,7 @@
#include <linux/poll.h>
#include <linux/nmi.h>
#include <linux/fs.h>
+#include <linux/trace.h>
#include <linux/sched/rt.h>
#include "trace.h"
@@ -2128,6 +2129,129 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
ftrace_trace_userstack(buffer, flags, pc);
}
+static void
+trace_process_export(struct trace_export *export,
+ struct ring_buffer_event *event)
+{
+ struct trace_entry *entry;
+ unsigned int size = 0;
+
+ entry = ring_buffer_event_data(event);
+ size = ring_buffer_event_length(event);
+ export->write(entry, size);
+}
+
+static DEFINE_MUTEX(ftrace_export_lock);
+
+static struct trace_export __rcu *ftrace_exports_list __read_mostly;
+
+static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
+
+static inline void ftrace_exports_enable(void)
+{
+ static_branch_enable(&ftrace_exports_enabled);
+}
+
+static inline void ftrace_exports_disable(void)
+{
+ static_branch_disable(&ftrace_exports_enabled);
+}
+
+void ftrace_exports(struct ring_buffer_event *event)
+{
+ struct trace_export *export;
+
+ preempt_disable_notrace();
+
+ export = rcu_dereference_raw_notrace(ftrace_exports_list);
+ while (export) {
+ trace_process_export(export, event);
+ export = rcu_dereference_raw_notrace(export->next);
+ }
+
+ preempt_enable_notrace();
+}
+
+static inline void
+add_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ rcu_assign_pointer(export->next, *list);
+ /*
+ * We are entering export into the list but another
+ * CPU might be walking that list. We need to make sure
+ * the export->next pointer is valid before another CPU sees
+ * the export pointer included into the list.
+ */
+ rcu_assign_pointer(*list, export);
+}
+
+static inline int
+rm_trace_export(struct trace_export **list, struct trace_export *export)
+{
+ struct trace_export **p;
+
+ for (p = list; *p != NULL; p = &(*p)->next)
+ if (*p == export)
+ break;
+
+ if (*p != export)
+ return -1;
+
+ rcu_assign_pointer(*p, (*p)->next);
+
+ return 0;
+}
+
+static inline void
+add_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ if (*list == NULL)
+ ftrace_exports_enable();
+
+ add_trace_export(list, export);
+}
+
+static inline int
+rm_ftrace_export(struct trace_export **list, struct trace_export *export)
+{
+ int ret;
+
+ ret = rm_trace_export(list, export);
+ if (*list == NULL)
+ ftrace_exports_disable();
+
+ return ret;
+}
+
+int register_ftrace_export(struct trace_export *export)
+{
+ if (WARN_ON_ONCE(!export->write))
+ return -1;
+
+ mutex_lock(&ftrace_export_lock);
+
+ add_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_ftrace_export);
+
+int unregister_ftrace_export(struct trace_export *export)
+{
+ int ret;
+
+ mutex_lock(&ftrace_export_lock);
+
+ ret = rm_ftrace_export(&ftrace_exports_list, export);
+
+ mutex_unlock(&ftrace_export_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(unregister_ftrace_export);
+
void
trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
@@ -2146,8 +2270,11 @@ trace_function(struct trace_array *tr,
entry->ip = ip;
entry->parent_ip = parent_ip;
- if (!call_filter_check_discard(call, entry, buffer, event))
+ if (!call_filter_check_discard(call, entry, buffer, event)) {
+ if (static_branch_unlikely(&ftrace_exports_enabled))
+ ftrace_exports(event);
__buffer_unlock_commit(buffer, event);
+ }
}
#ifdef CONFIG_STACKTRACE
--
2.7.4
^ permalink raw reply related
* [PATCH V9 2/6] stm class: ftrace: Add ftrace-export-over-stm driver
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
This patch adds a driver that models itself as an stm_source called
stm_ftrace. Once the stm device and stm_ftrace have been linked via
sysfs, the driver registers itself as a trace_export and everything
passed to the interface from Ftrace subsystem will end up in the STM
trace engine.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/stm/Kconfig | 11 ++++++
drivers/hwtracing/stm/Makefile | 2 +
drivers/hwtracing/stm/ftrace.c | 87 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+)
create mode 100644 drivers/hwtracing/stm/ftrace.c
diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig
index 847a39b..723e2d9 100644
--- a/drivers/hwtracing/stm/Kconfig
+++ b/drivers/hwtracing/stm/Kconfig
@@ -39,4 +39,15 @@ config STM_SOURCE_HEARTBEAT
If you want to send heartbeat messages over STM devices,
say Y.
+config STM_SOURCE_FTRACE
+ tristate "Copy the output from kernel Ftrace to STM engine"
+ depends on FUNCTION_TRACER
+ help
+ This option can be used to copy the output from kernel Ftrace
+ to STM engine. Enabling this option will introduce a slight
+ timing effect.
+
+ If you want to send kernel Ftrace messages over STM devices,
+ say Y.
+
endif
diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile
index a9ce3d4..3abd84c 100644
--- a/drivers/hwtracing/stm/Makefile
+++ b/drivers/hwtracing/stm/Makefile
@@ -6,6 +6,8 @@ obj-$(CONFIG_STM_DUMMY) += dummy_stm.o
obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o
obj-$(CONFIG_STM_SOURCE_HEARTBEAT) += stm_heartbeat.o
+obj-$(CONFIG_STM_SOURCE_FTRACE) += stm_ftrace.o
stm_console-y := console.o
stm_heartbeat-y := heartbeat.o
+stm_ftrace-y := ftrace.o
diff --git a/drivers/hwtracing/stm/ftrace.c b/drivers/hwtracing/stm/ftrace.c
new file mode 100644
index 0000000..bd126a7
--- /dev/null
+++ b/drivers/hwtracing/stm/ftrace.c
@@ -0,0 +1,87 @@
+/*
+ * Simple kernel driver to link kernel Ftrace and an STM device
+ * Copyright (c) 2016, Linaro Ltd.
+ *
+ * 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.
+ *
+ * STM Ftrace will be registered as a trace_export.
+ */
+
+#include <linux/module.h>
+#include <linux/stm.h>
+#include <linux/trace.h>
+
+#define STM_FTRACE_NR_CHANNELS 1
+#define STM_FTRACE_CHAN 0
+
+static int stm_ftrace_link(struct stm_source_data *data);
+static void stm_ftrace_unlink(struct stm_source_data *data);
+
+static struct stm_ftrace {
+ struct stm_source_data data;
+ struct trace_export ftrace;
+} stm_ftrace = {
+ .data = {
+ .name = "ftrace",
+ .nr_chans = STM_FTRACE_NR_CHANNELS,
+ .link = stm_ftrace_link,
+ .unlink = stm_ftrace_unlink,
+ },
+};
+
+/**
+ * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
+ * @buf: buffer containing the data packet
+ * @len: length of the data packet
+ */
+static void notrace
+stm_ftrace_write(const void *buf, unsigned int len)
+{
+ stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len);
+}
+
+static int stm_ftrace_link(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ sf->ftrace.write = stm_ftrace_write;
+
+ return register_ftrace_export(&sf->ftrace);
+}
+
+static void stm_ftrace_unlink(struct stm_source_data *data)
+{
+ struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
+
+ unregister_ftrace_export(&sf->ftrace);
+}
+
+static int __init stm_ftrace_init(void)
+{
+ int ret;
+
+ ret = stm_source_register_device(NULL, &stm_ftrace.data);
+ if (ret)
+ pr_err("Failed to register stm_source - ftrace.\n");
+
+ return ret;
+}
+
+static void __exit stm_ftrace_exit(void)
+{
+ stm_source_unregister_device(&stm_ftrace.data);
+}
+
+module_init(stm_ftrace_init);
+module_exit(stm_ftrace_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("stm_ftrace driver");
+MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
--
2.7.4
^ permalink raw reply related
* [PATCH V9 3/6] coresight: Mark stm_generic_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/coresight/coresight-stm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 49e0f1b..b7543bd 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -406,7 +406,7 @@ static long stm_generic_set_options(struct stm_data *stm_data,
return 0;
}
-static ssize_t stm_generic_packet(struct stm_data *stm_data,
+static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
unsigned int master,
unsigned int channel,
unsigned int packet,
--
2.7.4
^ permalink raw reply related
* [PATCH V9 4/6] intel_th: Mark sth_stm_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/intel_th/sth.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/intel_th/sth.c b/drivers/hwtracing/intel_th/sth.c
index e1aee61..b034446 100644
--- a/drivers/hwtracing/intel_th/sth.c
+++ b/drivers/hwtracing/intel_th/sth.c
@@ -67,10 +67,13 @@ static void sth_iowrite(void __iomem *dest, const unsigned char *payload,
}
}
-static ssize_t sth_stm_packet(struct stm_data *stm_data, unsigned int master,
- unsigned int channel, unsigned int packet,
- unsigned int flags, unsigned int size,
- const unsigned char *payload)
+static ssize_t notrace sth_stm_packet(struct stm_data *stm_data,
+ unsigned int master,
+ unsigned int channel,
+ unsigned int packet,
+ unsigned int flags,
+ unsigned int size,
+ const unsigned char *payload)
{
struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
struct intel_th_channel __iomem *out =
--
2.7.4
^ permalink raw reply related
* [PATCH V9 5/6] stm dummy: Mark dummy_stm_packet() with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/stm/dummy_stm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwtracing/stm/dummy_stm.c b/drivers/hwtracing/stm/dummy_stm.c
index a86612d..c5f94ca 100644
--- a/drivers/hwtracing/stm/dummy_stm.c
+++ b/drivers/hwtracing/stm/dummy_stm.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <linux/stm.h>
-static ssize_t
+static ssize_t notrace
dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
unsigned int channel, unsigned int packet, unsigned int flags,
unsigned int size, const unsigned char *payload)
--
2.7.4
^ permalink raw reply related
* [PATCH V9 6/6] stm: Mark the functions of writing STM with notrace
From: Chunyan Zhang @ 2016-11-21 7:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479715043-6534-1-git-send-email-zhang.chunyan@linaro.org>
If CONFIG_STM_SOURCE_FTRACE is selected, Function trace data can be
writen to sink via STM, all functions that related to writing data
packets to STM should be marked 'notrace' to avoid being traced by
Ftrace, otherwise the program would stall into an endless loop.
Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
---
drivers/hwtracing/stm/core.c | 7 ++++---
include/linux/stm.h | 4 ++--
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index 51f81d6..37d3bcb 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -425,7 +425,7 @@ static int stm_file_assign(struct stm_file *stmf, char *id, unsigned int width)
return ret;
}
-static ssize_t stm_write(struct stm_data *data, unsigned int master,
+static ssize_t notrace stm_write(struct stm_data *data, unsigned int master,
unsigned int channel, const char *buf, size_t count)
{
unsigned int flags = STP_PACKET_TIMESTAMPED;
@@ -1121,8 +1121,9 @@ void stm_source_unregister_device(struct stm_source_data *data)
}
EXPORT_SYMBOL_GPL(stm_source_unregister_device);
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
- const char *buf, size_t count)
+int notrace stm_source_write(struct stm_source_data *data,
+ unsigned int chan,
+ const char *buf, size_t count)
{
struct stm_source_device *src = data->src;
struct stm_device *stm;
diff --git a/include/linux/stm.h b/include/linux/stm.h
index 8369d8a..210ff22 100644
--- a/include/linux/stm.h
+++ b/include/linux/stm.h
@@ -133,7 +133,7 @@ int stm_source_register_device(struct device *parent,
struct stm_source_data *data);
void stm_source_unregister_device(struct stm_source_data *data);
-int stm_source_write(struct stm_source_data *data, unsigned int chan,
- const char *buf, size_t count);
+int notrace stm_source_write(struct stm_source_data *data, unsigned int chan,
+ const char *buf, size_t count);
#endif /* _STM_H_ */
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3] Documentation: dt: Add TI SCI clock driver
From: Tero Kristo @ 2016-11-21 8:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAL_JsqLtSs6ifnMdEOsfXpGoWnmXuGAx83+ziB9yU+zurvob+A@mail.gmail.com>
On 18/11/16 19:20, Rob Herring wrote:
> On Mon, Oct 31, 2016 at 7:50 AM, Tero Kristo <t-kristo@ti.com> wrote:
>> On 30/10/16 22:41, Rob Herring wrote:
>>>
>>> On Fri, Oct 21, 2016 at 03:45:59PM +0300, Tero Kristo wrote:
>>>>
>>>> Add a clock implementation, TI SCI clock, that will hook to the common
>>>> clock framework, and allow each clock to be controlled via TI SCI
>>>> protocol.
>>>>
>>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>>> ---
>>>> .../devicetree/bindings/clock/ti,sci-clk.txt | 37
>>>> ++++++++++++++++++++++
>>>> MAINTAINERS | 1 +
>>>> 2 files changed, 38 insertions(+)
>>>> create mode 100644
>>>> Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>>> b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>>> new file mode 100644
>>>> index 0000000..bfc3ca4
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>>> @@ -0,0 +1,37 @@
>>>> +Texas Instruments TI-SCI Clocks
>>>> +===============================
>>>> +
>>>> +All clocks on Texas Instruments' SoCs that contain a System Controller,
>>>> +are only controlled by this entity. Communication between a host
>>>> processor
>>>> +running an OS and the System Controller happens through a protocol known
>>>> +as TI-SCI[1]. This clock implementation plugs into the common clock
>>>> +framework and makes use of the TI-SCI protocol on clock API requests.
>>>> +
>>>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>> +
>>>> +Required properties:
>>>> +-------------------
>>>> +- compatible: Must be "ti,k2g-sci-clk"
>>>> +- #clock-cells: Shall be 2.
>>>> + In clock consumers, this cell represents the device ID and clock ID
>>>> + exposed by the PM firmware. The assignments can be found in the header
>>>> + files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
>>>> + <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
>>>> + is the SoC involved, for example 'k2g'.
>>>> +
>>>> +Examples:
>>>> +--------
>>>> +
>>>> +pmmc: pmmc {
>>>> + compatible = "ti,k2g-sci";
>>>> +
>>>> + k2g_clks: k2g_clks {
>>>
>>>
>>> Use "clocks" for node name instead.
>>>
>>>> + compatible = "ti,k2g-sci-clk";
>>>
>>>
>>> I'm starting to think all these child nodes for SCI are pointless. Is
>>> there any reason why the parent node can't be the clock provider (along
>>> with all the other providers it acks as)?
>>
>>
>> I believe the only reason to keep them separate is to have kernel side of
>> things modular. If we have separate nodes, the drivers can be probed
>> separately.
>>
>> If not, we need to build one huge blob with all the features in it, so the
>> main driver can probe everything in one go, with annoying back-and-forth
>> callbacks in place (assuming we still want to keep stuff somehow modular.)
>
> Since when is DT the only way to create a device? The main driver can
> create devices for all the sub-functions like clocks. This is the same
> as MFDs which have been done both ways.
Yes obviously this can be done, my main point was that it will require
building some sort of infra within the driver to handle this. With
separate nodes, none of this is going to be needed. Also, we will lose
any kind of configurability via DT if we don't have separate nodes; now
we can select the available clocks / genpds via the compatible string of
the clocks/genpd nodes themselves (this isn't clearly evident as of now
as we only support a grand total of one device, which is k2g-evm.)
Otherwise we need to probe against the main node and add a separate
compatible string for every device, and carry this information to the
sibling devices also somehow. It is just so much simpler if we can just
keep separate nodes for them.
Also, plenty of things are doing this kind of stuff already in
DT/kernel, having a parent node in place and sub-functions added
separately for ease of use, with apparently no visible point for having
the nodes within the DT.
-Tero
^ permalink raw reply
* [GIT PULL 1/10] mailbox: Add Tegra HSP driver
From: Thierry Reding @ 2016-11-21 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161119022742.GK2543@localhost>
On Fri, Nov 18, 2016 at 06:27:42PM -0800, Olof Johansson wrote:
> Hi,
>
> On Fri, Nov 18, 2016 at 05:17:10PM +0100, Thierry Reding wrote:
> > Hi ARM SoC maintainers,
> >
> > The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
> >
> > Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
> >
> > are available in the git repository at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.10-mailbox
> >
> > for you to fetch changes up to 68050eb6c611527232fe5574c7306e97e47499ef:
> >
> > mailbox: tegra-hsp: Use after free in tegra_hsp_remove_doorbells() (2016-11-18 14:32:13 +0100)
> >
> > Thanks,
> > Thierry
> >
> > ----------------------------------------------------------------
> > mailbox: Add Tegra HSP driver
> >
> > This contains the device tree bindings and a driver for the Tegra HSP, a
> > hardware block that provides hardware synchronization primitives and is
> > the foundation for inter-processor communication between CPU and BPMP.
> >
> > ----------------------------------------------------------------
> > Dan Carpenter (1):
> > mailbox: tegra-hsp: Use after free in tegra_hsp_remove_doorbells()
> >
> > Joseph Lo (2):
> > soc/tegra: Add Tegra186 support
>
> I don't think you really needed to merge this in here, since all you need it
> for is to fulfill the kconfig dependency and enable the driver, right? That'd
> happen when the driver and soc branch is merged at the toplevel anyway.
The reason I did this is that I wanted each branch to be buildable as a
way to confirm that the dependencies are correct. In order to do that I
need the Kconfig symbol to enable the driver.
I suppose there are other ways I could've done that, though. Maybe in
the future new SoC Kconfig symbols should just be introduced way ahead
of time, so that they're already in a release or two before actual code
starts to emerge.
> Anyhow, no damage done, I've merged this in. I would say that it'd be a little
> more logical to send the SoC branch before the driver branch given this
> dependency though.
The reason that the SoC branch was sent after is because only the first
commit in that branch was pulled into the mailbox branch.
In retrospect, I think perhaps a better approach would've been to have a
separate branch with only the Kconfig symbol addition and pull that in
where needed.
Thanks,
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/84d12034/attachment.sig>
^ permalink raw reply
* [GIT PULL 9/10] arm64: tegra: Device tree changes for v4.10-rc1
From: Thierry Reding @ 2016-11-21 8:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161119024021.GT2543@localhost>
On Fri, Nov 18, 2016 at 06:40:21PM -0800, Olof Johansson wrote:
> On Fri, Nov 18, 2016 at 05:17:18PM +0100, Thierry Reding wrote:
> > Hi ARM SoC maintainers,
> >
> > The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
> >
> > Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
> >
> > are available in the git repository at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.10-arm64-dt
> >
> > for you to fetch changes up to cc13b4fa4ac780cec6c21b64a39ab2950e95e8f6:
> >
> > arm64: tegra: Add NVIDIA P2771 board support (2016-11-18 14:35:53 +0100)
> >
> > Thanks,
> > Thierry
> >
> > ----------------------------------------------------------------
> > arm64: tegra: Device tree changes for v4.10-rc1
> >
> > This adds initial support for Tegra186, the P3310 processor module as
> > well as the P2771 development board. Not much is functional, but there
> > is enough to boot to an initial ramdisk with debug serial output.
> >
> > ----------------------------------------------------------------
> > Dan Carpenter (1):
> > mailbox: tegra-hsp: Use after free in tegra_hsp_remove_doorbells()
> >
> > Joseph Lo (6):
> > soc/tegra: Add Tegra186 support
> > dt-bindings: mailbox: Add Tegra HSP binding
> > dt-bindings: firmware: Add bindings for Tegra BPMP
> > arm64: tegra: Add Tegra186 support
> > arm64: tegra: Add NVIDIA P3310 processor module support
> > arm64: tegra: Add NVIDIA P2771 board support
> >
> > Stephen Warren (2):
> > dt-bindings: Add power domains to Tegra BPMP firmware
> > dt-bindings: firmware: Allow child nodes inside the Tegra BPMP
> >
> > Thierry Reding (12):
> > Merge branch 'for-4.10/soc' into for-4.10/mailbox
> > mailbox: Add Tegra HSP driver
> > Merge branch 'for-4.10/mailbox' into for-4.10/firmware
> > firmware: tegra: Add IVC library
> > firmware: tegra: Add BPMP support
> > Merge branch 'for-4.10/firmware' into for-4.10/arm64/dt
> > arm64: tegra: Add CPU nodes for Tegra186
> > arm64: tegra: Add serial ports on Tegra186
> > arm64: tegra: Add I2C controllers on Tegra186
> > arm64: tegra: Add SDHCI controllers on Tegra186
> > arm64: tegra: Add GPIO controllers on Tegra186
> > arm64: tegra: Enable PSCI on P3310
>
> The drivers->dt dependency here is annoying. Any chance you can respin without
> it?
>
> We've been encouraging people to consider using numerical clock/gpio/reset
> numbers on initial submission to avoid these dependencies on dt-bindings
> includes, and then follow up with a move to the symbolic names between -rc1 and
> -rc2. Mind doing the same here?
Yes, I can do that. Would it be acceptable to have a dt-bindings->dt
dependency? Stephen's already done a good job of avoiding this kind of
dependency by getting the bindings, and hence dt-bindings headers,
merged ahead of Linux kernel support because he had already gotten the
bindings reviewed and finalized during his work on U-Boot.
I've been told in the past that it's not necessary to strictly split DT
bindings patches from driver patches, but I suppose if a dt-bindings->dt
is acceptable, then splitting things up more strictly would actually be
the preferable solution here because it also avoids the slight churn of
converting to symbolic values later on.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/ca5e5c61/attachment-0001.sig>
^ permalink raw reply
* [GIT PULL 2/10] firmware: Add Tegra IVC and BPMP support
From: Thierry Reding @ 2016-11-21 8:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161119023138.GL2543@localhost>
On Fri, Nov 18, 2016 at 06:31:38PM -0800, Olof Johansson wrote:
> On Fri, Nov 18, 2016 at 05:17:11PM +0100, Thierry Reding wrote:
> > Hi ARM SoC maintainers,
> >
> > The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:
> >
> > Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)
> >
> > are available in the git repository at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.10-firmware
> >
> > for you to fetch changes up to b704ed8095ee91af5f3f7343bb3be23aae1cb26d:
> >
> > dt-bindings: firmware: Allow child nodes inside the Tegra BPMP (2016-11-18 14:33:44 +0100)
> >
> > Thanks,
> > Thierry
> >
> > ----------------------------------------------------------------
> > firmware: Add Tegra IVC and BPMP support
> >
> > IVC is an inter-processor communication protocol that uses shared memory
> > to exchange data between processors. The BPMP driver makes use of this
> > to communicate with the Boot and Power Management Processor (BPMP) and
> > uses an additional hardware synchronization primitive from the HSP block
> > to signal availability of new data (doorbell).
> >
> > Firmware running on the BPMP implements a number of services such as the
> > control of clocks and resets within the system, or the ability to ungate
> > or gate power partitions.
> >
> > ----------------------------------------------------------------
> > Dan Carpenter (1):
> > mailbox: tegra-hsp: Use after free in tegra_hsp_remove_doorbells()
> >
> > Joseph Lo (3):
> > soc/tegra: Add Tegra186 support
> > dt-bindings: mailbox: Add Tegra HSP binding
> > dt-bindings: firmware: Add bindings for Tegra BPMP
> >
> > Stephen Warren (2):
> > dt-bindings: Add power domains to Tegra BPMP firmware
> > dt-bindings: firmware: Allow child nodes inside the Tegra BPMP
> >
> > Thierry Reding (5):
> > Merge branch 'for-4.10/soc' into for-4.10/mailbox
> > mailbox: Add Tegra HSP driver
> > Merge branch 'for-4.10/mailbox' into for-4.10/firmware
> > firmware: tegra: Add IVC library
> > firmware: tegra: Add BPMP support
>
> Hi,
>
> Again the format of the pull request here is a little confusing, since it's
> a cumulative shotlog and diffstat, while you already sent the bulk of this
> as part of the driver branch (1/10). It'd have been better to use that branch
> as the base when you generate the pull request since that's the delta we see
> when we merge it in.
In the past there had been occasions where it hadn't been clear what a
given branch was going to pull in as additional dependencies, so adding
the complete shortlog seemed like a good way to document this in a more
explicit way.
If you prefer working things out yourself I can tweak the scripts to
generate the pull requests on top of their respective dependencies.
> Also, I can't seem to find the key you use to sign these tags with, it isn't
> uploaded on pgp.mit.edu. Can you remedy that please, and get it signed as
> needed?
Works for me:
http://pgp.mit.edu/pks/lookup?op=get&search=0xDD23ACD77F3EB3A1
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161121/a9fa1298/attachment.sig>
^ permalink raw reply
* [PATCH] spi: davinci: Allow device tree devices to use DMA
From: Sekhar Nori @ 2016-11-21 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <946d60bc-ac14-7934-c1b3-e2de03831459@lechnology.com>
On Sunday 20 November 2016 10:31 PM, David Lechner wrote:
> On 11/20/2016 06:59 AM, Sekhar Nori wrote:
>> On Saturday 19 November 2016 10:11 AM, David Lechner wrote:
>>> @@ -400,6 +401,9 @@ static int davinci_spi_of_setup(struct spi_device
>>> *spi)
>>> if (!of_property_read_u32(np, "ti,spi-wdelay", &prop))
>>> spicfg->wdelay = (u8)prop;
>>> spi->controller_data = spicfg;
>>> + /* Use DMA for device if master supports it */
>>> + if (dspi->dma_rx)
>>
>> This should be
>>
>> if (!(IS_ERR(dpsi->dma_rx) || IS_ERR(dspi->dma_tx))
>
>
> There is the following code in davinci_spi_probe():
>
> ret = davinci_spi_request_dma(dspi);
> if (ret == -EPROBE_DEFER) {
> goto free_clk;
> } else if (ret) {
> dev_info(&pdev->dev, "DMA is not supported (%d)\n", ret);
> dspi->dma_rx = NULL;
> dspi->dma_tx = NULL;
> }
>
> So, I does not look like it is possible to get anything other than NULL
> or a valid pointer for dpsi->dma_rx and that checking dpsi->dma_tx is
> not necessary.
>
> So, I think if (dspi->dma_rx) is sufficient. In fact the same check is
> used during unwinding if the probe function fails.
You are right, I see it now. Setting dma_rx to NULL overriding the error
value is confusing since dma_request_chan() itself does not use NULL as
an error value.
I think it is better to fix the existing code to remove the NULL
overwrite and use IS_ERR() instead. You should probably wait for some
feedback from the SPI maintainer though.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH] PCI: Add information about describing PCI in ACPI
From: Gabriele Paoloni @ 2016-11-21 8:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161118175404.GI25762@bhelgaas-glaptop.roam.corp.google.com>
Hi Bjorn
> -----Original Message-----
> From: Bjorn Helgaas [mailto:helgaas at kernel.org]
> Sent: 18 November 2016 17:54
> To: Gabriele Paoloni
> Cc: Bjorn Helgaas; linux-pci at vger.kernel.org; linux-
> acpi at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linaro-acpi at lists.linaro.org
> Subject: Re: [PATCH] PCI: Add information about describing PCI in ACPI
>
> On Fri, Nov 18, 2016 at 05:17:34PM +0000, Gabriele Paoloni wrote:
> > > -----Original Message-----
> > > From: linux-kernel-owner at vger.kernel.org [mailto:linux-kernel-
> > > owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
> > > Sent: 17 November 2016 18:00
>
> > > +Static tables like MCFG, HPET, ECDT, etc., are *not* mechanisms
> for
> > > +reserving address space! The static tables are for things the OS
> > > +needs to know early in boot, before it can parse the ACPI
> namespace.
> > > +If a new table is defined, an old OS needs to operate correctly
> even
> > > +though it ignores the table. _CRS allows that because it is
> generic
> > > +and understood by the old OS; a static table does not.
> >
> > Right so if my understanding is correct you are saying that resources
> > described in the MCFG table should also be declared in PNP0C02
> devices
> > so that the PNP driver can reserve these resources.
>
> Yes.
>
> > On the other side the PCI Root bridge driver should not reserve such
> > resources.
> >
> > Well if my understanding is correct I think we have a problem here:
> > http://lxr.free-electrons.com/source/drivers/pci/ecam.c#L74
> >
> > As you can see pci_ecam_create() will conflict with the pnp driver
> > as it will try to reserve the resources from the MCFG table...
> >
> > Maybe we need to rework pci_ecam_create() ?
>
> I think it's OK as it is.
>
> The pnp/system.c driver does try to reserve PNP0C02 resources, and it
> marks them as "not busy". That way they appear in /proc/iomem and
> won't be allocated for anything else, but they can still be requested
> by drivers, e.g., pci/ecam.c, which will mark them "busy".
>
> This is analogous to what the PCI core does in pci_claim_resource().
> This is really a function of the ACPI/PNP *core*, which should reserve
> all _CRS resources for all devices (not just PNP0C02 devices). But
> it's done by pnp/system.c, and only for PNP0C02, because there's a
> bunch of historical baggage there.
>
> You'll also notice that in this case, things are out of order:
> logically the pnp/system.c reservation should happen first, but in
> fact the pci/ecam.c request happens *before* the pnp/system.c one.
> That means the pnp/system.c one might fail and complain "[mem ...]
> could not be reserved".
Correct me if I am wrong...
So currently we are relying on the fact that pci_ecam_create() is called
before the pnp driver.
If the pnp driver came first we would end up in pci_ecam_create() failing
here:
http://lxr.free-electrons.com/source/drivers/pci/ecam.c#L76
I am not sure but it seems to me like a bit weak condition to rely on...
what about removing the error condition in pci_ecam_create() and logging
just a dev_info()?
Thanks
Gab
>
> Bjorn
^ permalink raw reply
* [PATCH v3 2/6] iio: adc: Add support for STM32 ADC core
From: Fabrice Gasnier @ 2016-11-21 8:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <09b63f8e-20c8-532e-2d97-2faa6dfe7538@kernel.org>
On 11/19/2016 01:17 PM, Jonathan Cameron wrote:
> On 15/11/16 15:30, Fabrice Gasnier wrote:
>> Add core driver for STMicroelectronics STM32 ADC (Analog to Digital
>> Converter). STM32 ADC can be composed of up to 3 ADCs with shared
>> resources like clock prescaler, common interrupt line and analog
>> reference voltage.
>> This core driver basically manages shared resources.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> There is nothing in here that demands selecting a fixed regulator.
> I've also switched the select regulator over to depends on inline with
> other drivers in IIO that have a hard dependency on regulators.
> Other than that which showed up during build tests, looks good to me.
> Shout if I've broken anything with this change.
Hi Jonathan, All,
First many thanks.
This is not a big deal. Only thing is: I think patch 4 of this series
(on stm32_defconfig) need to be updated
to accommodate this change. E.g. :
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
Shall I send a new version of this series (all patches), including your
changes, with updated defconfig as well ?
Or only updated patch on defconfig is enough ?
Please advise,
Fabrice
>
> Applied to the togreg branch of iio.git and pushed out as testing for
> the autobuilders to play with it.
>
> Thanks,
>
> Jonathan
>> ---
>> drivers/iio/adc/Kconfig | 13 ++
>> drivers/iio/adc/Makefile | 1 +
>> drivers/iio/adc/stm32-adc-core.c | 303 +++++++++++++++++++++++++++++++++++++++
>> drivers/iio/adc/stm32-adc-core.h | 52 +++++++
>> 4 files changed, 369 insertions(+)
>> create mode 100644 drivers/iio/adc/stm32-adc-core.c
>> create mode 100644 drivers/iio/adc/stm32-adc-core.h
>>
>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>> index 7edcf32..ff30239 100644
>> --- a/drivers/iio/adc/Kconfig
>> +++ b/drivers/iio/adc/Kconfig
>> @@ -419,6 +419,19 @@ config ROCKCHIP_SARADC
>> To compile this driver as a module, choose M here: the
>> module will be called rockchip_saradc.
>>
>> +config STM32_ADC_CORE
>> + tristate "STMicroelectronics STM32 adc core"
>> + depends on ARCH_STM32 || COMPILE_TEST
>> + depends on OF
>> + select REGULATOR
>> + select REGULATOR_FIXED_VOLTAGE
>> + help
>> + Select this option to enable the core driver for STMicroelectronics
>> + STM32 analog-to-digital converter (ADC).
>> +
>> + This driver can also be built as a module. If so, the module
>> + will be called stm32-adc-core.
>> +
>> config STX104
>> tristate "Apex Embedded Systems STX104 driver"
>> depends on X86 && ISA_BUS_API
>> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
>> index 7a40c04..a1e8f44 100644
>> --- a/drivers/iio/adc/Makefile
>> +++ b/drivers/iio/adc/Makefile
>> @@ -41,6 +41,7 @@ obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
>> obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
>> obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
>> obj-$(CONFIG_STX104) += stx104.o
>> +obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
>> obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>> obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
>> obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
>> diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c
>> new file mode 100644
>> index 0000000..4214b0c
>> --- /dev/null
>> +++ b/drivers/iio/adc/stm32-adc-core.c
>> @@ -0,0 +1,303 @@
>> +/*
>> + * This file is part of STM32 ADC driver
>> + *
>> + * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
>> + * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
>> + *
>> + * Inspired from: fsl-imx25-tsadc
>> + *
>> + * License type: GPLv2
>> + *
>> + * 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, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irqchip/chained_irq.h>
>> +#include <linux/irqdesc.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/slab.h>
>> +
>> +#include "stm32-adc-core.h"
>> +
>> +/* STM32F4 - common registers for all ADC instances: 1, 2 & 3 */
>> +#define STM32F4_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00)
>> +#define STM32F4_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x04)
>> +
>> +/* STM32F4_ADC_CSR - bit fields */
>> +#define STM32F4_EOC3 BIT(17)
>> +#define STM32F4_EOC2 BIT(9)
>> +#define STM32F4_EOC1 BIT(1)
>> +
>> +/* STM32F4_ADC_CCR - bit fields */
>> +#define STM32F4_ADC_ADCPRE_SHIFT 16
>> +#define STM32F4_ADC_ADCPRE_MASK GENMASK(17, 16)
>> +
>> +/* STM32 F4 maximum analog clock rate (from datasheet) */
>> +#define STM32F4_ADC_MAX_CLK_RATE 36000000
>> +
>> +/**
>> + * struct stm32_adc_priv - stm32 ADC core private data
>> + * @irq: irq for ADC block
>> + * @domain: irq domain reference
>> + * @aclk: clock reference for the analog circuitry
>> + * @vref: regulator reference
>> + * @common: common data for all ADC instances
>> + */
>> +struct stm32_adc_priv {
>> + int irq;
>> + struct irq_domain *domain;
>> + struct clk *aclk;
>> + struct regulator *vref;
>> + struct stm32_adc_common common;
>> +};
>> +
>> +static struct stm32_adc_priv *to_stm32_adc_priv(struct stm32_adc_common *com)
>> +{
>> + return container_of(com, struct stm32_adc_priv, common);
>> +}
>> +
>> +/* STM32F4 ADC internal common clock prescaler division ratios */
>> +static int stm32f4_pclk_div[] = {2, 4, 6, 8};
>> +
>> +/**
>> + * stm32f4_adc_clk_sel() - Select stm32f4 ADC common clock prescaler
>> + * @priv: stm32 ADC core private data
>> + * Select clock prescaler used for analog conversions, before using ADC.
>> + */
>> +static int stm32f4_adc_clk_sel(struct platform_device *pdev,
>> + struct stm32_adc_priv *priv)
>> +{
>> + unsigned long rate;
>> + u32 val;
>> + int i;
>> +
>> + rate = clk_get_rate(priv->aclk);
>> + for (i = 0; i < ARRAY_SIZE(stm32f4_pclk_div); i++) {
>> + if ((rate / stm32f4_pclk_div[i]) <= STM32F4_ADC_MAX_CLK_RATE)
>> + break;
>> + }
>> + if (i >= ARRAY_SIZE(stm32f4_pclk_div))
>> + return -EINVAL;
>> +
>> + val = readl_relaxed(priv->common.base + STM32F4_ADC_CCR);
>> + val &= ~STM32F4_ADC_ADCPRE_MASK;
>> + val |= i << STM32F4_ADC_ADCPRE_SHIFT;
>> + writel_relaxed(val, priv->common.base + STM32F4_ADC_CCR);
>> +
>> + dev_dbg(&pdev->dev, "Using analog clock source at %ld kHz\n",
>> + rate / (stm32f4_pclk_div[i] * 1000));
>> +
>> + return 0;
>> +}
>> +
>> +/* ADC common interrupt for all instances */
>> +static void stm32_adc_irq_handler(struct irq_desc *desc)
>> +{
>> + struct stm32_adc_priv *priv = irq_desc_get_handler_data(desc);
>> + struct irq_chip *chip = irq_desc_get_chip(desc);
>> + u32 status;
>> +
>> + chained_irq_enter(chip, desc);
>> + status = readl_relaxed(priv->common.base + STM32F4_ADC_CSR);
>> +
>> + if (status & STM32F4_EOC1)
>> + generic_handle_irq(irq_find_mapping(priv->domain, 0));
>> +
>> + if (status & STM32F4_EOC2)
>> + generic_handle_irq(irq_find_mapping(priv->domain, 1));
>> +
>> + if (status & STM32F4_EOC3)
>> + generic_handle_irq(irq_find_mapping(priv->domain, 2));
>> +
>> + chained_irq_exit(chip, desc);
>> +};
>> +
>> +static int stm32_adc_domain_map(struct irq_domain *d, unsigned int irq,
>> + irq_hw_number_t hwirq)
>> +{
>> + irq_set_chip_data(irq, d->host_data);
>> + irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_level_irq);
>> +
>> + return 0;
>> +}
>> +
>> +static void stm32_adc_domain_unmap(struct irq_domain *d, unsigned int irq)
>> +{
>> + irq_set_chip_and_handler(irq, NULL, NULL);
>> + irq_set_chip_data(irq, NULL);
>> +}
>> +
>> +static const struct irq_domain_ops stm32_adc_domain_ops = {
>> + .map = stm32_adc_domain_map,
>> + .unmap = stm32_adc_domain_unmap,
>> + .xlate = irq_domain_xlate_onecell,
>> +};
>> +
>> +static int stm32_adc_irq_probe(struct platform_device *pdev,
>> + struct stm32_adc_priv *priv)
>> +{
>> + struct device_node *np = pdev->dev.of_node;
>> +
>> + priv->irq = platform_get_irq(pdev, 0);
>> + if (priv->irq < 0) {
>> + dev_err(&pdev->dev, "failed to get irq\n");
>> + return priv->irq;
>> + }
>> +
>> + priv->domain = irq_domain_add_simple(np, STM32_ADC_MAX_ADCS, 0,
>> + &stm32_adc_domain_ops,
>> + priv);
>> + if (!priv->domain) {
>> + dev_err(&pdev->dev, "Failed to add irq domain\n");
>> + return -ENOMEM;
>> + }
>> +
>> + irq_set_chained_handler(priv->irq, stm32_adc_irq_handler);
>> + irq_set_handler_data(priv->irq, priv);
>> +
>> + return 0;
>> +}
>> +
>> +static void stm32_adc_irq_remove(struct platform_device *pdev,
>> + struct stm32_adc_priv *priv)
>> +{
>> + int hwirq;
>> +
>> + for (hwirq = 0; hwirq < STM32_ADC_MAX_ADCS; hwirq++)
>> + irq_dispose_mapping(irq_find_mapping(priv->domain, hwirq));
>> + irq_domain_remove(priv->domain);
>> + irq_set_chained_handler(priv->irq, NULL);
>> +}
>> +
>> +static int stm32_adc_probe(struct platform_device *pdev)
>> +{
>> + struct stm32_adc_priv *priv;
>> + struct device_node *np = pdev->dev.of_node;
>> + struct resource *res;
>> + int ret;
>> +
>> + if (!pdev->dev.of_node)
>> + return -ENODEV;
>> +
>> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv)
>> + return -ENOMEM;
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + priv->common.base = devm_ioremap_resource(&pdev->dev, res);
>> + if (IS_ERR(priv->common.base))
>> + return PTR_ERR(priv->common.base);
>> +
>> + priv->vref = devm_regulator_get(&pdev->dev, "vref");
>> + if (IS_ERR(priv->vref)) {
>> + ret = PTR_ERR(priv->vref);
>> + dev_err(&pdev->dev, "vref get failed, %d\n", ret);
>> + return ret;
>> + }
>> +
>> + ret = regulator_enable(priv->vref);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "vref enable failed\n");
>> + return ret;
>> + }
>> +
>> + ret = regulator_get_voltage(priv->vref);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "vref get voltage failed, %d\n", ret);
>> + goto err_regulator_disable;
>> + }
>> + priv->common.vref_mv = ret / 1000;
>> + dev_dbg(&pdev->dev, "vref+=%dmV\n", priv->common.vref_mv);
>> +
>> + priv->aclk = devm_clk_get(&pdev->dev, "adc");
>> + if (IS_ERR(priv->aclk)) {
>> + ret = PTR_ERR(priv->aclk);
>> + dev_err(&pdev->dev, "Can't get 'adc' clock\n");
>> + goto err_regulator_disable;
>> + }
>> +
>> + ret = clk_prepare_enable(priv->aclk);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "adc clk enable failed\n");
>> + goto err_regulator_disable;
>> + }
>> +
>> + ret = stm32f4_adc_clk_sel(pdev, priv);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "adc clk selection failed\n");
>> + goto err_clk_disable;
>> + }
>> +
>> + ret = stm32_adc_irq_probe(pdev, priv);
>> + if (ret < 0)
>> + goto err_clk_disable;
>> +
>> + platform_set_drvdata(pdev, &priv->common);
>> +
>> + ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "failed to populate DT children\n");
>> + goto err_irq_remove;
>> + }
>> +
>> + return 0;
>> +
>> +err_irq_remove:
>> + stm32_adc_irq_remove(pdev, priv);
>> +
>> +err_clk_disable:
>> + clk_disable_unprepare(priv->aclk);
>> +
>> +err_regulator_disable:
>> + regulator_disable(priv->vref);
>> +
>> + return ret;
>> +}
>> +
>> +static int stm32_adc_remove(struct platform_device *pdev)
>> +{
>> + struct stm32_adc_common *common = platform_get_drvdata(pdev);
>> + struct stm32_adc_priv *priv = to_stm32_adc_priv(common);
>> +
>> + of_platform_depopulate(&pdev->dev);
>> + stm32_adc_irq_remove(pdev, priv);
>> + clk_disable_unprepare(priv->aclk);
>> + regulator_disable(priv->vref);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id stm32_adc_of_match[] = {
>> + { .compatible = "st,stm32f4-adc-core" },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, stm32_adc_of_match);
>> +
>> +static struct platform_driver stm32_adc_driver = {
>> + .probe = stm32_adc_probe,
>> + .remove = stm32_adc_remove,
>> + .driver = {
>> + .name = "stm32-adc-core",
>> + .of_match_table = stm32_adc_of_match,
>> + },
>> +};
>> +module_platform_driver(stm32_adc_driver);
>> +
>> +MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
>> +MODULE_DESCRIPTION("STMicroelectronics STM32 ADC core driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("platform:stm32-adc-core");
>> diff --git a/drivers/iio/adc/stm32-adc-core.h b/drivers/iio/adc/stm32-adc-core.h
>> new file mode 100644
>> index 0000000..081fa5f
>> --- /dev/null
>> +++ b/drivers/iio/adc/stm32-adc-core.h
>> @@ -0,0 +1,52 @@
>> +/*
>> + * This file is part of STM32 ADC driver
>> + *
>> + * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
>> + * Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
>> + *
>> + * License type: GPLv2
>> + *
>> + * 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, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef __STM32_ADC_H
>> +#define __STM32_ADC_H
>> +
>> +/*
>> + * STM32 - ADC global register map
>> + * ________________________________________________________
>> + * | Offset | Register |
>> + * --------------------------------------------------------
>> + * | 0x000 | Master ADC1 |
>> + * --------------------------------------------------------
>> + * | 0x100 | Slave ADC2 |
>> + * --------------------------------------------------------
>> + * | 0x200 | Slave ADC3 |
>> + * --------------------------------------------------------
>> + * | 0x300 | Master & Slave common regs |
>> + * --------------------------------------------------------
>> + */
>> +#define STM32_ADC_MAX_ADCS 3
>> +#define STM32_ADCX_COMN_OFFSET 0x300
>> +
>> +/**
>> + * struct stm32_adc_common - stm32 ADC driver common data (for all instances)
>> + * @base: control registers base cpu addr
>> + * @vref_mv: vref voltage (mv)
>> + */
>> +struct stm32_adc_common {
>> + void __iomem *base;
>> + int vref_mv;
>> +};
>> +
>> +#endif
>>
^ permalink raw reply
* [PATCH v2] ARM: Drop fixed 200 Hz timer requirement from Samsung platforms
From: Ben Dooks @ 2016-11-21 8:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+Ln22GyRwywcxdO4Gp67d8TfpjfNzaE0z25=WW9GWibjGkDuQ@mail.gmail.com>
On 21/11/16 06:01, Tomasz Figa wrote:
> 2016-11-18 17:46 GMT+09:00 Arnd Bergmann <arnd@arndb.de>:
>> Maybe add a paragraph about the specific problem:
>>
>> "On s3c24xx, the PWM counter is only 16 bit wide, and with the
>> typical 12MHz input clock that overflows every 5.5ms. This works
>> with HZ=200 or higher but not with HZ=100 which needs a 10ms
>> interval between ticks. On Later chips (S3C64xx, S5P and EXYNOS),
>> the counter is 32 bits and does not have this problem.
>> The new samsung_pwm_timer driver solves the problem by scaling
>> the input clock by a factor of 50 on s3c24xx, which makes it
>> less accurate but allows HZ=100 as well as CONFIG_NO_HZ with
>> fewer wakeups".
>
> One thing to correct here is that the typical clock is PCLK, which is
> derived from one of the PLLs and AFAIR is between 33-66 MHz on
> s3c24xx. Technically you can drive the PWM block from an external
> clock (12 MHz for some board-file based boards), but for simplicity
> this functionality was omitted in the new PWM timer driver used for DT
> boards (which worked fine with the PWM driven by PCLK).
Given it was a clock mux option, that would not have been difficult to
acheive. However these platforms are now so old people don't care, I
think all my pre-armv7 stuff is now in a box.
The use of the 12MHz input was to give something to run PWM timers from
that wasn't interrupted by cpu frequency scaling as PCLK generally is
half HCLK which is divided down from the core CPU clock.
(Later devices had multiple PLL sources so you didn't have to have the
CPU fed from the same clock as the peripherals)
> Also I'm wondering if the divisor we use right now for 16-bit timers
> isn't too small, since it gives us a really short wraparound time,
> which means getting more timer interrupts for longer intervals, kind
> of defeating the benefit of tickless mode. However, AFAICT it doesn't
> affect the HZ problem.
The original implementation was to go for the best accuracy from the
timer at the expense of 200 irqs per second instead of the usual 100.
> Best regards.
> Tomasz
>
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
^ permalink raw reply
* [PATCH] mtd: nand: tango: Use nand_to_mtd() instead of directly accessing chip->mtd
From: Boris Brezillon @ 2016-11-21 9:03 UTC (permalink / raw)
To: linux-arm-kernel
The nand_to_mtd() helper is here to hide internal mtd_info <-> nand_chip
association and ease future refactors.
Make use of this helper instead of directly accessing chip->mtd.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/mtd/nand/tango_nand.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/tango_nand.c
index 7ed35348993e..ec87516b87f5 100644
--- a/drivers/mtd/nand/tango_nand.c
+++ b/drivers/mtd/nand/tango_nand.c
@@ -171,6 +171,7 @@ static void tango_select_chip(struct mtd_info *mtd, int idx)
*/
static int check_erased_page(struct nand_chip *chip, u8 *buf)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
u8 *meta = chip->oob_poi + BBM_SIZE;
u8 *ecc = chip->oob_poi + BBM_SIZE + METADATA_SIZE;
const int ecc_size = chip->ecc.bytes;
@@ -183,7 +184,7 @@ static int check_erased_page(struct nand_chip *chip, u8 *buf)
meta, meta_len,
chip->ecc.strength);
if (res < 0)
- chip->mtd.ecc_stats.failed++;
+ mtd->ecc_stats.failed++;
bitflips = max(res, bitflips);
buf += pkt_size;
@@ -300,26 +301,30 @@ static int tango_write_page(struct mtd_info *mtd, struct nand_chip *chip,
static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+
*pos += len;
if (!*buf) {
/* skip over "len" bytes */
- chip->cmdfunc(&chip->mtd, NAND_CMD_RNDOUT, *pos, -1);
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, *pos, -1);
} else {
- tango_read_buf(&chip->mtd, *buf, len);
+ tango_read_buf(mtd, *buf, len);
*buf += len;
}
}
static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+
*pos += len;
if (!*buf) {
/* skip over "len" bytes */
- chip->cmdfunc(&chip->mtd, NAND_CMD_SEQIN, *pos, -1);
+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, *pos, -1);
} else {
- tango_write_buf(&chip->mtd, *buf, len);
+ tango_write_buf(mtd, *buf, len);
*buf += len;
}
}
@@ -345,8 +350,9 @@ static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos)
*/
static void raw_read(struct nand_chip *chip, u8 *buf, u8 *oob)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
u8 *oob_orig = oob;
- const int page_size = chip->mtd.writesize;
+ const int page_size = mtd->writesize;
const int ecc_size = chip->ecc.bytes;
const int pkt_size = chip->ecc.size;
int pos = 0; /* position within physical page */
@@ -371,8 +377,9 @@ static void raw_read(struct nand_chip *chip, u8 *buf, u8 *oob)
static void raw_write(struct nand_chip *chip, const u8 *buf, const u8 *oob)
{
+ struct mtd_info *mtd = nand_to_mtd(chip);
const u8 *oob_orig = oob;
- const int page_size = chip->mtd.writesize;
+ const int page_size = mtd->writesize;
const int ecc_size = chip->ecc.bytes;
const int pkt_size = chip->ecc.size;
int pos = 0; /* position within physical page */
@@ -522,7 +529,7 @@ static int chip_init(struct device *dev, struct device_node *np)
chip = &tchip->nand_chip;
ecc = &chip->ecc;
- mtd = &chip->mtd;
+ mtd = nand_to_mtd(chip);
chip->read_byte = tango_read_byte;
chip->write_buf = tango_write_buf;
@@ -584,7 +591,7 @@ static int tango_nand_remove(struct platform_device *pdev)
for (cs = 0; cs < MAX_CS; ++cs) {
if (nfc->chips[cs])
- nand_release(&nfc->chips[cs]->nand_chip.mtd);
+ nand_release(nand_to_mtd(&nfc->chips[cs]->nand_chip));
}
return 0;
--
2.7.4
^ permalink raw reply related
* [PATCH v2] ARM: Drop fixed 200 Hz timer requirement from Samsung platforms
From: Russell King - ARM Linux @ 2016-11-21 9:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d67d8100-c8bf-d353-2225-e3b869a1c90d@codethink.co.uk>
On Mon, Nov 21, 2016 at 08:59:06AM +0000, Ben Dooks wrote:
> On 21/11/16 06:01, Tomasz Figa wrote:
> >2016-11-18 17:46 GMT+09:00 Arnd Bergmann <arnd@arndb.de>:
> >>Maybe add a paragraph about the specific problem:
> >>
> >>"On s3c24xx, the PWM counter is only 16 bit wide, and with the
> >>typical 12MHz input clock that overflows every 5.5ms. This works
> >>with HZ=200 or higher but not with HZ=100 which needs a 10ms
> >>interval between ticks. On Later chips (S3C64xx, S5P and EXYNOS),
> >>the counter is 32 bits and does not have this problem.
> >>The new samsung_pwm_timer driver solves the problem by scaling
> >>the input clock by a factor of 50 on s3c24xx, which makes it
> >>less accurate but allows HZ=100 as well as CONFIG_NO_HZ with
> >>fewer wakeups".
> >
> >One thing to correct here is that the typical clock is PCLK, which is
> >derived from one of the PLLs and AFAIR is between 33-66 MHz on
> >s3c24xx. Technically you can drive the PWM block from an external
> >clock (12 MHz for some board-file based boards), but for simplicity
> >this functionality was omitted in the new PWM timer driver used for DT
> >boards (which worked fine with the PWM driven by PCLK).
>
> Given it was a clock mux option, that would not have been difficult to
> acheive. However these platforms are now so old people don't care, I
> think all my pre-armv7 stuff is now in a box.
However, there are still s3c2410 machines running out there... so we
should do our best not to break them.
> The use of the 12MHz input was to give something to run PWM timers from
> that wasn't interrupted by cpu frequency scaling as PCLK generally is
> half HCLK which is divided down from the core CPU clock.
...
> The original implementation was to go for the best accuracy from the
> timer at the expense of 200 irqs per second instead of the usual 100.
This sounds like a good enough reason not to switch away from using 200Hz
and the 12MHz input.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [kvm-unit-tests PATCH v9 2/3] arm: pmu: Check cycle count increases
From: Andrew Jones @ 2016-11-21 9:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479528942-21866-3-git-send-email-wei@redhat.com>
On Fri, Nov 18, 2016 at 10:15:41PM -0600, Wei Huang wrote:
> From: Christopher Covington <cov@codeaurora.org>
>
> Ensure that reads of the PMCCNTR_EL0 are monotonically increasing,
> even for the smallest delta of two subsequent reads.
>
> Signed-off-by: Christopher Covington <cov@codeaurora.org>
> Signed-off-by: Wei Huang <wei@redhat.com>
> ---
> arm/pmu.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 156 insertions(+)
>
> diff --git a/arm/pmu.c b/arm/pmu.c
> index 9d9c53b..fa87de4 100644
> --- a/arm/pmu.c
> +++ b/arm/pmu.c
> @@ -15,6 +15,9 @@
> #include "libcflat.h"
> #include "asm/barrier.h"
>
> +#define PMU_PMCR_E (1 << 0)
> +#define PMU_PMCR_C (1 << 2)
> +#define PMU_PMCR_LC (1 << 6)
> #define PMU_PMCR_N_SHIFT 11
> #define PMU_PMCR_N_MASK 0x1f
> #define PMU_PMCR_ID_SHIFT 16
> @@ -22,6 +25,14 @@
> #define PMU_PMCR_IMP_SHIFT 24
> #define PMU_PMCR_IMP_MASK 0xff
>
> +#define ID_DFR0_PERFMON_SHIFT 24
> +#define ID_DFR0_PERFMON_MASK 0xf
> +
> +#define PMU_CYCLE_IDX 31
> +
> +#define NR_SAMPLES 10
> +
> +static unsigned int pmu_version;
> #if defined(__arm__)
> static inline uint32_t pmcr_read(void)
> {
> @@ -30,6 +41,69 @@ static inline uint32_t pmcr_read(void)
> asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (ret));
> return ret;
> }
> +
> +static inline void pmcr_write(uint32_t value)
> +{
> + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (value));
> + isb();
> +}
> +
> +static inline void pmselr_write(uint32_t value)
> +{
> + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (value));
> + isb();
> +}
> +
> +static inline void pmxevtyper_write(uint32_t value)
> +{
> + asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (value));
> +}
> +
> +static inline uint64_t pmccntr_read(void)
> +{
> + uint32_t lo, hi = 0;
> +
> + if (pmu_version == 0x3)
> + asm volatile("mrrc p15, 0, %0, %1, c9" : "=r" (lo), "=r" (hi));
> + else
> + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (lo));
This is fine for this single test, but I was actually thinking we'd
implement both the 32-bit and 64-bit accessors separately, allowing
us to add an additional test that tries both on AArch32 (PMUv3). I.e.
report_prefix_push("pmccntr");
report("32-bit read", pmccntr_read() != 0); /* test mrc access */
if (pmu_version == 0x3) {
u64 cntr64 = pmccntr_read64(); /* test mrrc access */
report("64-bit read", (cntr64 >> 32) == 0 && (u32)cntr64 != 0);
} else {
report_skip("64-bit read, PMUv3 required");
}
We can refactor when we add that test later though.
> +
> + return ((uint64_t)hi << 32) | lo;
> +}
> +
> +static inline void pmccntr_write(uint64_t value)
> +{
> + uint32_t lo, hi;
> +
> + lo = value & 0xffffffff;
> + hi = (value >> 32) & 0xffffffff;
> +
> + if (pmu_version == 0x3)
> + asm volatile("mcrr p15, 0, %0, %1, c9" : : "r" (lo), "r" (hi));
> + else
> + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (lo));
> +}
> +
> +static inline void pmcntenset_write(uint32_t value)
> +{
> + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (value));
> +}
> +
> +/* PMCCFILTR is an obsolete name for PMXEVTYPER31 in ARMv7 */
> +static inline void pmccfiltr_write(uint32_t value)
> +{
> + pmselr_write(PMU_CYCLE_IDX);
> + pmxevtyper_write(value);
> + isb();
> +}
> +
> +static inline uint32_t id_dfr0_read(void)
> +{
> + uint32_t val;
> +
> + asm volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (val));
> + return val;
> +}
> #elif defined(__aarch64__)
> static inline uint32_t pmcr_read(void)
> {
> @@ -38,6 +112,44 @@ static inline uint32_t pmcr_read(void)
> asm volatile("mrs %0, pmcr_el0" : "=r" (ret));
> return ret;
> }
> +
> +static inline void pmcr_write(uint32_t value)
> +{
> + asm volatile("msr pmcr_el0, %0" : : "r" (value));
> + isb();
> +}
> +
> +static inline uint64_t pmccntr_read(void)
> +{
> + uint64_t cycles;
> +
> + asm volatile("mrs %0, pmccntr_el0" : "=r" (cycles));
> + return cycles;
> +}
> +
> +static inline void pmccntr_write(uint64_t value)
> +{
> + asm volatile("msr pmccntr_el0, %0" : : "r" (value));
> +}
> +
> +static inline void pmcntenset_write(uint32_t value)
> +{
> + asm volatile("msr pmcntenset_el0, %0" : : "r" (value));
> +}
> +
> +static inline void pmccfiltr_write(uint32_t value)
> +{
> + asm volatile("msr pmccfiltr_el0, %0" : : "r" (value));
> + isb();
> +}
> +
> +static inline uint32_t id_dfr0_read(void)
> +{
> + uint32_t id;
> +
> + asm volatile("mrs %0, id_dfr0_el1" : "=r" (id));
> + return id;
> +}
> #endif
>
> /*
> @@ -64,11 +176,55 @@ static bool check_pmcr(void)
> return ((pmcr >> PMU_PMCR_IMP_SHIFT) & PMU_PMCR_IMP_MASK) != 0;
> }
>
> +/*
> + * Ensure that the cycle counter progresses between back-to-back reads.
> + */
> +static bool check_cycles_increase(void)
> +{
> + bool success = true;
> +
> + pmccntr_write(0);
> + pmcr_write(pmcr_read() | PMU_PMCR_LC | PMU_PMCR_C | PMU_PMCR_E);
> +
> + for (int i = 0; i < NR_SAMPLES; i++) {
> + uint64_t a, b;
> +
> + a = pmccntr_read();
> + b = pmccntr_read();
> +
> + if (a >= b) {
> + printf("Read %"PRId64" then %"PRId64".\n", a, b);
> + success = false;
> + break;
> + }
> + }
> +
> + pmcr_write(pmcr_read() & ~PMU_PMCR_E);
> +
> + return success;
> +}
> +
> +void pmu_init(void)
> +{
> + uint32_t dfr0;
> +
> + /* probe pmu version */
> + dfr0 = id_dfr0_read();
> + pmu_version = (dfr0 >> ID_DFR0_PERFMON_SHIFT) & ID_DFR0_PERFMON_MASK;
> + printf("PMU version: %d\n", pmu_version);
> +
> + /* init for PMU event access, right now only care about cycle count */
> + pmcntenset_write(1 << PMU_CYCLE_IDX);
> + pmccfiltr_write(0); /* count cycles in EL0, EL1, but not EL2 */
These last two register writes are specific to the cycle count test, so
I don't think they belong in a common pmu_init function. I'd keep them
at the top of check_cycles_increase.
> +}
> +
> int main(void)
> {
> report_prefix_push("pmu");
>
> + pmu_init();
> report("Control register", check_pmcr());
> + report("Monotonically increasing cycle count", check_cycles_increase());
>
> return report_summary();
> }
> --
> 1.8.3.1
>
Thanks,
drew
^ permalink raw reply
* [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S family flash
From: Yao Yuan @ 2016-11-21 9:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM4PR0701MB21302252988A38FE2A393FE4FEB50@AM4PR0701MB2130.eurprd07.prod.outlook.com>
On Thu, Nov 21, 2016 at 03:15 PM +0800, Krzeminski, Marcin (Nokia - PL/Wroclaw) wrote:
> > -----Original Message-----
> > From: Yao Yuan [mailto:yao.yuan at nxp.com]
> > Sent: Monday, November 21, 2016 7:28 AM
> > To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> > <marcin.krzeminski@nokia.com>; Han Xu <xhnjupt@gmail.com>
> > Cc: David Woodhouse <dwmw2@infradead.org>; linux-
> > kernel at vger.kernel.org; linux-mtd at lists.infradead.org;
> > han.xu at freescale.com; Brian Norris <computersforpeace@gmail.com>;
> > jagannadh.teki at gmail.com; linux-arm-kernel at lists.infradead.org;
> > Cyrille Pitchen <cyrille.pitchen@atmel.com>
> > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S
> > family flash
> >
> > On Thu, Nov 18, 2016 at 07:00 PM +0000, Krzeminski, Marcin (Nokia -
> > PL/Wroclaw) wrote:
> > > > -----Original Message-----
> > > > From: Yao Yuan [mailto:yao.yuan at nxp.com]
> > > > Sent: Friday, November 18, 2016 5:20 AM
> > > > To: Krzeminski, Marcin (Nokia - PL/Wroclaw)
> > > > <marcin.krzeminski@nokia.com>; Han Xu <xhnjupt@gmail.com>
> > > > Cc: David Woodhouse <dwmw2@infradead.org>; linux-
> > > > kernel at vger.kernel.org; linux-mtd at lists.infradead.org;
> > > > han.xu at freescale.com; Brian Norris <computersforpeace@gmail.com>;
> > > > jagannadh.teki at gmail.com; linux-arm-kernel at lists.infradead.org
> > > > Subject: RE: [PATCH v3 6/9] mtd: spi-nor: Support R/W for S25FS-S
> > > > family flash
> > > >
> > > > On Thu, Nov 17, 2016 at 10:14:55AM +0000, Krzeminski, Marcin
> > > > (Nokia
> > > > -
> > > > PL/Wroclaw) wrote:
> > > > > > On Thu, Nov 17, 2016 at 06:50:55AM +0000, Krzeminski, Marcin
> > > > > > (Nokia
> > > > > > -
> > > > > > PL/Wroclaw) wrote:
> > > > > > > > > > On Thu, Aug 18, 2016 at 2:38 AM, Yunhui Cui
> > > > > > > > > > <B56489@freescale.com>
> > > > > > > > > > wrote:
> > > > > > > > > > > From: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > > > >
> > > > > > > > > > > With the physical sectors combination, S25FS-S
> > > > > > > > > > > family flash requires some special operations for
> > > > > > > > > > > read/write
> > functions.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
> > > > > > > > > > > ---
> > > > > > > > > > > drivers/mtd/spi-nor/spi-nor.c | 56
> > > > > > > > > > > +++++++++++++++++++++++++++++++++++++++++++
> > > > > > > > > > > 1 file changed, 56 insertions(+)
> > > > > > > > > > >
> > > > > > > > > > > diff --git a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > > b/drivers/mtd/spi-nor/spi-nor.c index
> > > > > > > > > > > d0fc165..495d0bb
> > > > > > > > > > > 100644
> > > > > > > > > > > --- a/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > > > > > > > > > > @@ -39,6 +39,10 @@
> > > > > > > > > > >
> > > > > > > > > > > #define SPI_NOR_MAX_ID_LEN 6
> > > > > > > > > > > #define SPI_NOR_MAX_ADDR_WIDTH 4
> > > > > > > > > > > +/* Added for S25FS-S family flash */
> > > > > > > > > > > +#define SPINOR_CONFIG_REG3_OFFSET 0x800004
> > > > > > > > > > > +#define CR3V_4KB_ERASE_UNABLE 0x8 #define
> > > > > > > > > > > +SPINOR_S25FS_FAMILY_EXT_JEDEC 0x81
> > > > > > > > > > >
> > > > > > > > > > > struct flash_info {
> > > > > > > > > > > char *name;
> > > > > > > > > > > @@ -78,6 +82,7 @@ struct flash_info { };
> > > > > > > > > > >
> > > > > > > > > > > #define JEDEC_MFR(info) ((info)->id[0])
> > > > > > > > > > > +#define EXT_JEDEC(info) ((info)->id[5])
> > > > > > > > > > >
> > > > > > > > > > > static const struct flash_info
> > > > > > > > > > > *spi_nor_match_id(const char *name);
> > > > > > > > > > >
> > > > > > > > > > > @@ -899,6 +904,7 @@ static const struct flash_info
> > > > spi_nor_ids[] = {
> > > > > > > > > > > */
> > > > > > > > > > > { "s25sl032p", INFO(0x010215, 0x4d00, 64 *
> > > > > > > > > > > 1024, 64,
> > > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > > > { "s25sl064p", INFO(0x010216, 0x4d00, 64 *
> > > > > > > > > > > 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> > },
> > > > > > > > > > > + { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64
> > > > > > > > > > > + * 1024, 512, 0)},
> > > > > > > > > > > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 *
> > > > > > > > > > > 1024, 128,
> > 0) },
> > > > > > > > > > > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 *
> > > > > > > > > > > 1024, 512,
> > > > > > > > > > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> > > > > > > > > > > { "s25fl512s", INFO(0x010220, 0x4d00, 256 *
> > > > > > > > > > > 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> > },
> > > @@
> > > > > > > > > > > -
> > > > 1036,6
> > > > > > > > +1042,50
> > > > > > > > > > @@ static const struct flash_info
> > > > > > > > > > *spi_nor_read_id(struct spi_nor
> > > > > > > > > > *nor)
> > > > > > > > > > > return ERR_PTR(-ENODEV); }
> > > > > > > > > > >
> > > > > > > > > > > +/*
> > > > > > > > > > > + * The S25FS-S family physical sectors may be
> > > > > > > > > > > +configured as a
> > > > > > > > > > > + * hybrid combination of eight 4-kB parameter
> > > > > > > > > > > +sectors
> > > > > > > > > > > + * at the top or bottom of the address space with
> > > > > > > > > > > +all
> > > > > > > > > > > + * but one of the remaining sectors being uniform size.
> > > > > > > > > > > + * The Parameter Sector Erase commands (20h or 21h)
> > > > > > > > > > > +must
> > > > > > > > > > > + * be used to erase the 4-kB parameter sectors individually.
> > > > > > > > > > > + * The Sector (uniform sector) Erase commands (D8h
> > > > > > > > > > > +or
> > > > > > > > > > > +DCh)
> > > > > > > > > > > + * must be used to erase any of the remaining
> > > > > > > > > > > + * sectors, including the portion of highest or
> > > > > > > > > > > +lowest address
> > > > > > > > > > > + * sector that is not overlaid by the parameter sectors.
> > > > > > > > > > > + * The uniform sector erase command has no effect
> > > > > > > > > > > +on parameter
> > > > > > > > > > sectors.
> > > > > > > > > > > + */
> > > > > > > > > > > +static int spansion_s25fs_disable_4kb_erase(struct
> > > > > > > > > > > +spi_nor
> > > > *nor) {
> > > > > > > > > > > + u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
> > > > > > > > > > > + u8 cr3v = 0x0;
> > > > > > > > > > > + int ret = 0x0;
> > > > > > > > > > > +
> > > > > > > > > > > + nor->cmd_buf[2] = cr3v_addr >> 16;
> > > > > > > > > > > + nor->cmd_buf[1] = cr3v_addr >> 8;
> > > > > > > > > > > + nor->cmd_buf[0] = cr3v_addr >> 0;
> > > > > > > > > > > +
> > > > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > > > &cr3v, 1);
> > > > > > > > > > > + if (ret)
> > > > > > > > > > > + return ret;
> > > > > > > > > > > + if (cr3v & CR3V_4KB_ERASE_UNABLE)
> > > > > > > > > > > + return 0;
> > > > > > > > > > > + ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> > > > > > > > > > > + if (ret)
> > > > > > > > > > > + return ret;
> > > > > > > > > > > + cr3v = CR3V_4KB_ERASE_UNABLE;
> > > > > > > > > > > + nor->program_opcode =
> > SPINOR_OP_SPANSION_WRAR;
> > > > > > > > > > > + nor->write(nor, cr3v_addr, 1, &cr3v);
> > > > > > > > > > > +
> > > > > > > > > > > + ret = nor->read_reg(nor,
> > > > > > > > > > > + SPINOR_OP_SPANSION_RDAR,
> > > > > > &cr3v, 1);
> > > > > > > > > > > + if (ret)
> > > > > > > > > > > + return ret;
> > > > > > > > > > > + if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
> > > > > > > > > > > + return -EPERM;
> > > > > > > > > > > +
> > > > > > > > > > > + return 0;
> > > > > > > > > > > +}
> > > > > > > > > > > +
> > > > > > > > > > > static int spi_nor_read(struct mtd_info *mtd,
> > > > > > > > > > > loff_t from, size_t
> > > > > > len,
> > > > > > > > > > > size_t *retlen, u_char *buf)
> > > > > > > > > > > { @@
> > > > > > > > > > > -1361,6
> > > > > > > > > > > +1411,12 @@ int spi_nor_scan(struct spi_nor *nor,
> > > > > > > > > > > +const char *name,
> > > > > > > > > > enum read_mode mode)
> > > > > > > > > > > spi_nor_wait_till_ready(nor);
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > + if (EXT_JEDEC(info) ==
> > > > > > > > > > > + SPINOR_S25FS_FAMILY_EXT_JEDEC)
> > > > {
> > > > > > > > > > > + ret = spansion_s25fs_disable_4kb_erase(nor);
> > > > > > > > > > > + if (ret)
> > > > > > > > > > > + return ret;
> > > > > > > > > > > + }
> > > > > > > > > > > +
> > > > > > > > > > > if (!mtd->name)
> > > > > > > > > > > mtd->name = dev_name(dev);
> > > > > > > > > > > mtd->priv = nor;
> > > > > > > > > > > --
> > > > > > > > > > > 2.1.0.27.g96db324
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > Hi Brian, I will ack this change but still feel it's
> > > > > > > > > > kind of hacking
> > code.
> > > > > > > > > >
> > > > > > > > > > Acked-by: Han xu <han.xu@nxp.com>
> > > > > > > > >
> > > > > > > > > I am new on the list so I am not sure if this topic has
> > > > > > > > > been
> > discussed.
> > > > > > > > > Generally our product functionality relay on those 4KiB sectors.
> > > > > > > > > I know that this hack is already in u-boot, but if you
> > > > > > > > > mainstream this you will force users of those 4KiB
> > > > > > > > > sectors to do hack the
> > > > > hack...
> > > > > > > > > I believe the proper solution here is to use erase
> > > > > > > > > regions functionality, I send and RFS about that some time ago.
> > > > > > > >
> > > > > > > > Do you mind to send me a link for reference?
> > > > > > > >
> > > > > > > Han,
> > > > > > >
> > > > > > > Sorry, It seem I have not posted erase region changes (only
> > > > > > > those regarding DUAL/QUAD I/O).
> > > > > > > Generally, in this flash you need to create 3 erase regions
> > > > > > > (because in FS-S family support only 4KiB erase on
> > > > > > > parameters sector -
> > > > eg.
> > > > > > > 1.2.2.4 in
> > > > > > S25FS512S).
> > > > > > > In my case regions are:
> > > > > > > 1. 0-32KiB (8*4KiB) - 4K_ERASE (0x20/0x21) 2. 32 - 256 -
> > > > > > > SE_CMD
> > > > > > (0xd8/0xdc) 3.
> > > > > > > Rest of the flash SE_CMD (0xd8/0xdc)
> > > > > > >
> > > > > > > To erase whole flash you can also use CHIP_ERASE_CMD
> > > > > > > (0x60/0xC7) command, you just need to add one more mtd
> > > > > > > partition that will cover
> > > > > > whole flash.
> > > > > > >
> > > > > >
> > > > > > Hi Krzeminski,
> > > > > >
> > > > > > Do you think is there any great advantages for enable 4KB?
> > > > > > Because for NXP(Freescale) QSPI controller, there is only
> > > > > > support max to 16 groups command.
> > > > > >
> > > > > > So It's hard to give 3 groups command just for erase
> > > > > > (0x21,0xdc and
> > 0xc7).
> > > > > > So we have to disable the 4kb erase and only use 256kbytes in
> > > > > > this
> > patch.
> > > > > >
> > > > > Yes, if you disable parameters sector in spi-nor framework you
> > > > > will disable it for all spi-nor clients not only for NXP QSPI controller.
> > > > > There are users (at least me) that relay on parameters sector
> > functionality.
> > > > This patch will brake it.
> > > > >
> > > > > Thanks,
> > > >
> > > > Hi Krzeminski,
> > > >
> > > > Get it.
> > > > So do you think how about that I add a flag in dts to select it?
> > > > The user want's disable 4kb, he can add the flag.
> > > >
> > > > In spi-nor.c:
> > > > if (of_property_read_bool(np, "spi-nor, disable-4kb")) {
> > > > spansion_s25fs_disable_4kb_erase();
> > > > }
> > > > else
> > > > ...
> > > >
> > > > In dts:
> > > >
> > > > &qspi {
> > > > num-cs = <2>;
> > > > bus-num = <0>;
> > > > status = "okay";
> > > >
> > > > qflash0: s25fs512s at 0 {
> > > > compatible = "spansion, s25fs512s";
> > > > spi-nor, disable-4kb
> > > > #address-cells = <1>;
> > > > #size-cells = <1>;
> > > > spi-max-frequency = <20000000>;
> > > > reg = <0>;
> > > > };
> > > >
> > > > I think it should be a better way.
> > > >
> > > > How about your think?
> > >
> > > This looks much better - at least for me.
> > > There are some parameters in JESD216 standard regarding parameters
> > > sector, but unfortunately I have not investigated that. You can take
> > > a look at Cyrille series, that adds support for JESD216 standard.
> > >
> >
> > Ok, I will resend v4 for add this.
> >
> > BTW, the 4-kytes block for S25FS is just only the first 8 blocks, the
> > other block is 256kytes.
> > Do out SPI-NOR support erase those specific combination?
> >
> > If not, do you have any plan for add it?
> > It seems I can't fine the support in spi-nor.
> >
> Those erase regions are solution for such flash, current upstream version does
> not have this. My solution is not universal, so probably I will not add it.
>
Ok, Get it.
We will not use the specific 4kb combination mode for S25FS also.
So I will add the patch to disable 4kb for S25FS. But I will add a flag in dts that
the user can do the choice.
Thanks.
^ permalink raw reply
* [PATCH] mfd: twl-core: export twl_get_regmap
From: Lee Jones @ 2016-11-21 9:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKP5S=3quz8f1H0xnaffJ35L8qSOpSkBEGS8GsNhB5F=v3DoBg@mail.gmail.com>
On Sun, 20 Nov 2016, Nicolae Rosia wrote:
> On Fri, Nov 18, 2016 at 8:55 PM, Lee Jones <lee.jones@linaro.org> wrote:
> > On Sat, 12 Nov 2016, Nicolae Rosia wrote:
> >
> >> We want to get rid of global twl_i2c_{write/read}.
> >> As a first step, allow clients to get the regmap and write directly
> >
> > What's stopping you from passing it through device data?
> >
> Could you elaborate a bit?
> The regmaps are stored in struct twl_client [0], stored in struct
> twl_private [1], both structs are defined in the source file, not in
> header.
> I could however just fix the problem by reworking the struct, exposing
> it and use mfd_add_device as real mfd drivers do.
Woah! Thanks for prompting me to read this driver. It's a bit of a
mess isn't it? I think it would be best to convert it to use the MFD
API, yes.
It's common place to pass shared resources such as 'regmap' though
device data. You can find many examples of *__set_drvdata throughout
the kernel.
> [0] http://lxr.free-electrons.com/source/drivers/mfd/twl-core.c#L152
> [1] http://lxr.free-electrons.com/source/drivers/mfd/twl-core.c#L163
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v2] ARM: Drop fixed 200 Hz timer requirement from Samsung platforms
From: Russell King - ARM Linux @ 2016-11-21 9:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+Ln22GyRwywcxdO4Gp67d8TfpjfNzaE0z25=WW9GWibjGkDuQ@mail.gmail.com>
On Mon, Nov 21, 2016 at 03:01:57PM +0900, Tomasz Figa wrote:
> One thing to correct here is that the typical clock is PCLK, which is
> derived from one of the PLLs and AFAIR is between 33-66 MHz on
> s3c24xx. Technically you can drive the PWM block from an external
> clock (12 MHz for some board-file based boards), but for simplicity
> this functionality was omitted in the new PWM timer driver used for DT
> boards (which worked fine with the PWM driven by PCLK).
So that's a knowingly-made regression for s3c24xx then. Pretty
disgusting developer behavior to do that, IMHO.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ 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