* [PATCH 0/5] powerpc, perf: BHRB based branch stack enablement on POWER8
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
Branch History Rolling Buffer (BHRB) is a new PMU feaure in IBM
POWER8 processor which records the branch instructions inside the execution
pipeline. This patchset enables the basic functionality of the feature through
generic perf branch stack sampling framework.
Sample output
-------------
$./perf record -b top
$./perf report
Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
# ........ ....... .................... ...................................... .................... ...................................
#
7.82% top libc-2.11.2.so [k] _IO_vfscanf libc-2.11.2.so [k] _IO_vfscanf
6.17% top libc-2.11.2.so [k] _IO_vfscanf [unknown] [k] 00000000
2.37% top [unknown] [k] 0xf7aafb30 [unknown] [k] 00000000
1.80% top [unknown] [k] 0x0fe07978 libc-2.11.2.so [k] _IO_vfscanf
1.60% top libc-2.11.2.so [k] _IO_vfscanf [kernel.kallsyms] [k] .do_task_stat
1.20% top [kernel.kallsyms] [k] .do_task_stat [kernel.kallsyms] [k] .do_task_stat
1.02% top libc-2.11.2.so [k] vfprintf libc-2.11.2.so [k] vfprintf
0.92% top top [k] _init [unknown] [k] 0x0fe037f4
Anshuman Khandual (5):
powerpc, perf: Add new BHRB related instructions on POWER8
powerpc, perf: Add basic assembly code to read BHRB entries on POWER8
powerpc, perf: Add new BHRB related generic functions, data and flags
powerpc, perf: Define BHRB generic functions, data and flags for POWER8
powerpc, perf: Enable branch stack sampling framework support with BHRB
arch/powerpc/include/asm/perf_event_server.h | 6 ++
arch/powerpc/include/asm/ppc-opcode.h | 7 ++
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/bhrb.S | 34 ++++++++++
arch/powerpc/perf/core-book3s.c | 96 +++++++++++++++++++++++++++-
arch/powerpc/perf/perf_event_bhrb.c | 75 ++++++++++++++++++++++
arch/powerpc/perf/power8-pmu.c | 57 ++++++++++++++++-
7 files changed, 272 insertions(+), 5 deletions(-)
create mode 100644 arch/powerpc/perf/bhrb.S
create mode 100644 arch/powerpc/perf/perf_event_bhrb.c
--
1.7.11.7
^ permalink raw reply
* [PATCH 4/5] powerpc, perf: Define BHRB generic functions, data and flags for POWER8
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366117000-10979-1-git-send-email-khandual@linux.vnet.ibm.com>
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/power8-pmu.c | 57 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 106ae0b..153408c 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -109,6 +109,16 @@
#define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
#define EVENT_PSEL_MASK 0xff /* PMCxSEL value */
+/* MMCRA IFM bits - POWER8 */
+#define POWER8_MMCRA_IFM1 0x0000000040000000UL
+#define POWER8_MMCRA_IFM2 0x0000000080000000UL
+#define POWER8_MMCRA_IFM3 0x00000000C0000000UL
+
+#define ONLY_PLM \
+ (PERF_SAMPLE_BRANCH_USER |\
+ PERF_SAMPLE_BRANCH_KERNEL |\
+ PERF_SAMPLE_BRANCH_HV)
+
/*
* Layout of constraint bits:
*
@@ -428,6 +438,48 @@ static int power8_generic_events[] = {
[PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
};
+static u64 power8_bhrb_filter_map(u64 branch_sample_type)
+{
+ u64 pmu_bhrb_filter = 0;
+ u64 br_privilege = branch_sample_type & ONLY_PLM;
+
+ /* BHRB and regular PMU events share the same prvillege state
+ * filter configuration. BHRB is always recorded along with a
+ * regular PMU event. So privilege state filter criteria for BHRB
+ * and the companion PMU events has to be the same. As a default
+ * "perf record" tool sets all privillege bits ON when no filter
+ * criteria is provided in the command line. So as along as all
+ * privillege bits are ON or they are OFF, we are good to go.
+ */
+ if ((br_privilege != 7) && (br_privilege != 0))
+ return -1;
+
+ /* No branch filter requested */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
+ return pmu_bhrb_filter;
+
+ /* Invalid branch filter options - HW does not support */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
+ pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
+ return pmu_bhrb_filter;
+ }
+
+ /* Every thing else is unsupported */
+ return -1;
+}
+
+static void power8_config_bhrb(u64 pmu_bhrb_filter)
+{
+ /* Enable BHRB filter in PMU */
+ mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
+}
+
static struct power_pmu power8_pmu = {
.name = "POWER8",
.n_counter = 6,
@@ -435,12 +487,15 @@ static struct power_pmu power8_pmu = {
.add_fields = POWER8_ADD_FIELDS,
.test_adder = POWER8_TEST_ADDER,
.compute_mmcr = power8_compute_mmcr,
+ .config_bhrb = power8_config_bhrb,
+ .bhrb_filter_map = power8_bhrb_filter_map,
.get_constraint = power8_get_constraint,
.disable_pmc = power8_disable_pmc,
- .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER,
+ .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB,
.n_generic = ARRAY_SIZE(power8_generic_events),
.generic_events = power8_generic_events,
.attr_groups = power8_pmu_attr_groups,
+ .bhrb_nr = 32,
};
static int __init init_power8_pmu(void)
--
1.7.11.7
^ permalink raw reply related
* [PATCH 5/5] powerpc, perf: Enable branch stack sampling framework support with BHRB
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366117000-10979-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch provides basic enablement for perf branch stack sampling framework
on POWER8 processor with a new PMU feature called BHRB (Branch History Rolling
Buffer).
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/core-book3s.c | 96 +++++++++++++++++++++++++++++++++++--
arch/powerpc/perf/perf_event_bhrb.c | 75 +++++++++++++++++++++++++++++
2 files changed, 168 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/perf/perf_event_bhrb.c
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4ac6e64..f4d1347 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -19,6 +19,8 @@
#include <asm/firmware.h>
#include <asm/ptrace.h>
+#define BHRB_MAX_ENTRIES 32
+
struct cpu_hw_events {
int n_events;
int n_percpu;
@@ -38,11 +40,21 @@ struct cpu_hw_events {
unsigned int group_flag;
int n_txn_start;
+
+ /* BHRB bits */
+ u64 bhrb_filter; /* BHRB HW branch filter */
+ int bhrb_users;
+ void *bhrb_context;
+ struct perf_branch_stack bhrb_stack;
+ struct perf_branch_entry bhrb_entries[BHRB_MAX_ENTRIES];
};
+
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
struct power_pmu *ppmu;
+#include "perf_event_bhrb.c"
+
/*
* Normally, to ignore kernel events we set the FCS (freeze counters
* in supervisor mode) bit in MMCR0, but if the kernel runs with the
@@ -858,6 +870,9 @@ static void power_pmu_enable(struct pmu *pmu)
}
out:
+ if (cpuhw->bhrb_users)
+ ppmu->config_bhrb(cpuhw->bhrb_filter);
+
local_irq_restore(flags);
}
@@ -888,6 +903,47 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
+/* Reset all possible BHRB entries */
+static void power_pmu_bhrb_reset(void)
+{
+ asm volatile(PPC_CLRBHRB);
+}
+
+void power_pmu_bhrb_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+ if (!ppmu->bhrb_nr)
+ return;
+
+ /* Clear BHRB if we changed task context to avoid data leaks */
+ if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
+ power_pmu_bhrb_reset();
+ cpuhw->bhrb_context = event->ctx;
+ }
+ cpuhw->bhrb_users++;
+}
+
+void power_pmu_bhrb_disable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+ if (!ppmu->bhrb_nr)
+ return;
+
+ cpuhw->bhrb_users--;
+ WARN_ON_ONCE(cpuhw->bhrb_users < 0);
+
+ if (!cpuhw->disabled && !cpuhw->bhrb_users) {
+ /* BHRB cannot be turned off when other
+ * events are active on the PMU.
+ */
+
+ /* avoid stale pointer */
+ cpuhw->bhrb_context = NULL;
+ }
+}
+
/*
* Add a event to the PMU.
* If all events are not already frozen, then we disable and
@@ -947,6 +1003,9 @@ nocheck:
ret = 0;
out:
+ if (has_branch_stack(event))
+ power_pmu_bhrb_enable(event);
+
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
return ret;
@@ -999,6 +1058,9 @@ static void power_pmu_del(struct perf_event *event, int ef_flags)
cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE);
}
+ if (has_branch_stack(event))
+ power_pmu_bhrb_disable(event);
+
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
@@ -1117,6 +1179,15 @@ int power_pmu_commit_txn(struct pmu *pmu)
return 0;
}
+/* Called from ctxsw to prevent one process's branch entries to
+ * mingle with the other process's entries during context switch.
+ */
+void power_pmu_flush_branch_stack(void)
+{
+ if (ppmu->bhrb_nr)
+ power_pmu_bhrb_reset();
+}
+
/*
* Return 1 if we might be able to put event on a limited PMC,
* or 0 if not.
@@ -1231,9 +1302,11 @@ static int power_pmu_event_init(struct perf_event *event)
if (!ppmu)
return -ENOENT;
- /* does not support taken branch sampling */
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
+ if (has_branch_stack(event)) {
+ /* PMU has BHRB enabled */
+ if (!(ppmu->flags & PPMU_BHRB))
+ return -EOPNOTSUPP;
+ }
switch (event->attr.type) {
case PERF_TYPE_HARDWARE:
@@ -1314,6 +1387,15 @@ static int power_pmu_event_init(struct perf_event *event)
cpuhw = &get_cpu_var(cpu_hw_events);
err = power_check_constraints(cpuhw, events, cflags, n + 1);
+
+ if (has_branch_stack(event)) {
+ cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
+ event->attr.branch_sample_type);
+
+ if(cpuhw->bhrb_filter == -1)
+ return -EOPNOTSUPP;
+ }
+
put_cpu_var(cpu_hw_events);
if (err)
return -EINVAL;
@@ -1372,6 +1454,7 @@ struct pmu power_pmu = {
.cancel_txn = power_pmu_cancel_txn,
.commit_txn = power_pmu_commit_txn,
.event_idx = power_pmu_event_idx,
+ .flush_branch_stack = power_pmu_flush_branch_stack,
};
@@ -1433,6 +1516,13 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
if (event->attr.sample_type & PERF_SAMPLE_ADDR)
perf_get_data_addr(regs, &data.addr);
+ if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) {
+ struct cpu_hw_events *cpuhw;
+ cpuhw = &__get_cpu_var(cpu_hw_events);
+ power_pmu_bhrb_read(cpuhw);
+ data.br_stack = &cpuhw->bhrb_stack;
+ }
+
if (perf_event_overflow(event, &data, regs))
power_pmu_stop(event, 0);
}
diff --git a/arch/powerpc/perf/perf_event_bhrb.c b/arch/powerpc/perf/perf_event_bhrb.c
new file mode 100644
index 0000000..5beddef
--- /dev/null
+++ b/arch/powerpc/perf/perf_event_bhrb.c
@@ -0,0 +1,75 @@
+#define BHRB_TARGET 0x0000000000000002
+#define BHRB_PREDICTION 0x0000000000000001
+#define BHRB_EA 0xFFFFFFFFFFFFFFFC
+
+extern unsigned long int read_bhrb(int n);
+
+void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
+{
+ u64 val;
+ u64 addr;
+ int r_index, u_index, target, pred;
+
+ r_index = 0;
+ u_index = 0;
+ while (r_index < ppmu->bhrb_nr) {
+ /* Assembly read function */
+ val = read_bhrb(r_index);
+
+ /* Terminal marker: End of valid BHRB entries */
+ if (val == 0) {
+ break;
+ } else {
+ /* BHRB field break up */
+ addr = val & BHRB_EA;
+ pred = val & BHRB_PREDICTION;
+ target = val & BHRB_TARGET;
+
+ /* Probable Missed entry: Not applicable for POWER8 */
+ if ((addr == 0) && (target == 0) && (pred == 1)) {
+ r_index++;
+ continue;
+ }
+
+ /* Real Missed entry: Power8 based missed entry */
+ if ((addr == 0) && (target == 1) && (pred == 1)) {
+ r_index++;
+ continue;
+ }
+
+ /* Reserved condition: Not a valid entry */
+ if ((addr == 0) && (target == 1) && (pred == 0)) {
+ r_index++;
+ continue;
+ }
+
+ /* Is a target address */
+ if (val & BHRB_TARGET) {
+ /* First address cannot be a target address */
+ if (r_index == 0) {
+ r_index++;
+ continue;
+ }
+
+ /* Update target address for the previous entry */
+ cpuhw->bhrb_entries[u_index - 1].to = addr;
+ cpuhw->bhrb_entries[u_index - 1].mispred = pred;
+ cpuhw->bhrb_entries[u_index - 1].predicted = ~pred;
+
+ /* Dont increment u_index */
+ r_index++;
+ } else {
+ /* Update address, flags for current entry */
+ cpuhw->bhrb_entries[u_index].from = addr;
+ cpuhw->bhrb_entries[u_index].mispred = pred;
+ cpuhw->bhrb_entries[u_index].predicted = ~pred;
+
+ /* Successfully popullated one entry */
+ u_index++;
+ r_index++;
+ }
+ }
+ }
+ cpuhw->bhrb_stack.nr = u_index;
+ return;
+}
--
1.7.11.7
^ permalink raw reply related
* [PATCH 3/5] powerpc, perf: Add new BHRB related generic functions, data and flags
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366117000-10979-1-git-send-email-khandual@linux.vnet.ibm.com>
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/perf_event_server.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 57b42da..3f0c15c 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -33,6 +33,8 @@ struct power_pmu {
unsigned long *valp);
int (*get_alternatives)(u64 event_id, unsigned int flags,
u64 alt[]);
+ u64 (*bhrb_filter_map)(u64 branch_sample_type);
+ void (*config_bhrb)(u64 pmu_bhrb_filter);
void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
int (*limited_pmc_event)(u64 event_id);
u32 flags;
@@ -42,6 +44,9 @@ struct power_pmu {
int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+ /* BHRB entries in the PMU */
+ int bhrb_nr;
};
/*
@@ -54,6 +59,7 @@ struct power_pmu {
#define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
#define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
+#define PPMU_BHRB 0x00000080 /* has BHRB feature enabled */
/*
* Values for flags to get_alternatives()
--
1.7.11.7
^ permalink raw reply related
* [PATCH 1/5] powerpc, perf: Add new BHRB related instructions on POWER8
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366117000-10979-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds new instructions support for reading various
BHRB entries and also clearing the BHRB buffer.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 8752bc8..93ae5a1 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -82,6 +82,7 @@
#define __REGA0_R31 31
/* sorted alphabetically */
+#define PPC_INST_BHRBE 0x7c00025c
#define PPC_INST_DCBA 0x7c0005ec
#define PPC_INST_DCBA_MASK 0xfc0007fe
#define PPC_INST_DCBAL 0x7c2005ec
@@ -297,6 +298,12 @@
#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
+/* BHRB instructions */
+#define PPC_CLRBHRB stringify_in_c(.long 0x7c00035c)
+#define PPC_MFBHRBE(r, n) stringify_in_c(.long PPC_INST_BHRBE | \
+ __PPC_RS(r) | \
+ (((n) & 0x1f) << 11))
+
/* Transactional memory instructions */
#define TRECHKPT stringify_in_c(.long PPC_INST_TRECHKPT)
#define TRECLAIM(r) stringify_in_c(.long PPC_INST_TRECLAIM \
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/5] powerpc, perf: Add basic assembly code to read BHRB entries on POWER8
From: Anshuman Khandual @ 2013-04-16 12:56 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366117000-10979-1-git-send-email-khandual@linux.vnet.ibm.com>
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/bhrb.S | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/perf/bhrb.S
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 472db18..510fae1 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -2,7 +2,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-$(CONFIG_PERF_EVENTS) += callchain.o
-obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o
+obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
power5+-pmu.o power6-pmu.o power7-pmu.o \
power8-pmu.o
diff --git a/arch/powerpc/perf/bhrb.S b/arch/powerpc/perf/bhrb.S
new file mode 100644
index 0000000..cffb815
--- /dev/null
+++ b/arch/powerpc/perf/bhrb.S
@@ -0,0 +1,34 @@
+#include <asm/ppc_asm.h>
+#include <asm/ppc-opcode.h>
+
+ .text
+
+.balign 8
+
+/* r3 = n (where n = [0-1023])
+ * The maximum number of BHRB entries supported with PPC_MFBHRBE instruction
+ * is 1024. We have limited number of table entries here as POWER8 implements
+ * 32 BHRB entries.
+ */
+
+/* .global read_bhrb */
+_GLOBAL(read_bhrb)
+ cmpldi r3,1023
+ bgt 1f
+ ld r4,bhrb_table@got(r2)
+ sldi r3,r3,3
+ add r3,r4,r3
+ mtctr r3
+ bctr
+1: li r3,0
+ blr
+
+#define MFBHRB_TABLE1(n) PPC_MFBHRBE(R3,n); blr
+#define MFBHRB_TABLE2(n) MFBHRB_TABLE1(n); MFBHRB_TABLE1(n+1)
+#define MFBHRB_TABLE4(n) MFBHRB_TABLE2(n); MFBHRB_TABLE2(n+2)
+#define MFBHRB_TABLE8(n) MFBHRB_TABLE4(n); MFBHRB_TABLE4(n+4)
+#define MFBHRB_TABLE16(n) MFBHRB_TABLE8(n); MFBHRB_TABLE8(n+8)
+#define MFBHRB_TABLE32(n) MFBHRB_TABLE16(n); MFBHRB_TABLE16(n+16)
+
+bhrb_table:
+ MFBHRB_TABLE32(0)
--
1.7.11.7
^ permalink raw reply related
* [PATCH] powerpc/corenet/config: add missing SCSI configs for corenet64_smp_defconfig
From: Shaohui Xie @ 2013-04-16 12:28 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: Shaohui Xie
Otherwise there will be no SCSI device nodes.
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
arch/powerpc/configs/corenet64_smp_defconfig | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 83dcc6a..2333e9b 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -77,6 +77,13 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_EEPROM_LEGACY=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=y
CONFIG_ATA=y
CONFIG_SATA_FSL=y
CONFIG_SATA_SIL24=y
--
1.7.0.4
^ permalink raw reply related
* [PATCH] powerpc/corenet/config: add missing SCSI configs for corenet64_smp_defconfig
From: Shaohui Xie @ 2013-04-16 12:47 UTC (permalink / raw)
To: linuxppc-dev, galak; +Cc: Shaohui Xie
Otherwise there will be no SCSI device nodes.
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
resend due to patch work did not capture this patch.
arch/powerpc/configs/corenet64_smp_defconfig | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 83dcc6a..2333e9b 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -77,6 +77,13 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
CONFIG_EEPROM_LEGACY=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=y
CONFIG_ATA=y
CONFIG_SATA_FSL=y
CONFIG_SATA_SIL24=y
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v7 0/3] of/pci: Provide common support for PCI DT parsing
From: Jason Cooper @ 2013-04-16 15:05 UTC (permalink / raw)
To: Andrew Murray
Cc: linux-mips, siva.kallam, linux-pci, linus.walleij, thierry.reding,
Liviu.Dudau, paulus, linux-samsung-soc, linux, jg1.han,
jgunthorpe, thomas.abraham, arnd, devicetree-discuss, rob.herring,
kgene.kim, bhelgaas, linux-arm-kernel, thomas.petazzoni, monstr,
linux-kernel, suren.reddy, linuxppc-dev
In-Reply-To: <1366107508-12672-1-git-send-email-Andrew.Murray@arm.com>
On Tue, Apr 16, 2013 at 11:18:25AM +0100, Andrew Murray wrote:
> This patchset factors out duplicated code associated with parsing PCI
> DT "ranges" properties across the architectures and introduces a
> "ranges" parser. This parser "of_pci_range_parser" can be used directly
> by ARM host bridge drivers enabling them to obtain ranges from device
> trees.
>
> I've included the Reviewed-by and Tested-by's received from v5/v6 in this
> patchset, earlier versions of this patchset (v3) have been tested-by:
>
> Thierry Reding <thierry.reding@avionic-design.de>
> Jingoo Han <jg1.han@samsung.com>
>
> I've tested that this patchset builds and runs on ARM and that it builds on
> PowerPC and x86_64.
Series replaces v6 in mvebu/drivers
thx,
Jason.
>
> Compared to the v6 sent by Andrew Murray, the following changes have
> been made in response to build errors/warnings:
>
> * Inclusion of linux/of_address.h in of_pci.c as suggested by Michal
> Simek to prevent compilation failures on Microblaze (and others) and his
> ack.
>
> * Use of externs, static inlines and a typo in linux/of_address.h in response
> to linker errors (multiple defination) on x86_64 as spotted by a kbuild test
> robot on (jcooper/linux.git mvebu/drivers)
>
> * Add EXPORT_SYMBOL_GPL to of_pci_range_parser function to be consistent
> with of_pci_process_ranges function
^ permalink raw reply
* [PATCH V2 1/5] powerpc, perf: Add new BHRB related instructions on POWER8
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366127650-1952-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds new instructions support for reading various
BHRB entries and also clearing the BHRB buffer.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index 8752bc8..93ae5a1 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -82,6 +82,7 @@
#define __REGA0_R31 31
/* sorted alphabetically */
+#define PPC_INST_BHRBE 0x7c00025c
#define PPC_INST_DCBA 0x7c0005ec
#define PPC_INST_DCBA_MASK 0xfc0007fe
#define PPC_INST_DCBAL 0x7c2005ec
@@ -297,6 +298,12 @@
#define PPC_NAP stringify_in_c(.long PPC_INST_NAP)
#define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP)
+/* BHRB instructions */
+#define PPC_CLRBHRB stringify_in_c(.long 0x7c00035c)
+#define PPC_MFBHRBE(r, n) stringify_in_c(.long PPC_INST_BHRBE | \
+ __PPC_RS(r) | \
+ (((n) & 0x1f) << 11))
+
/* Transactional memory instructions */
#define TRECHKPT stringify_in_c(.long PPC_INST_TRECHKPT)
#define TRECLAIM(r) stringify_in_c(.long PPC_INST_TRECLAIM \
--
1.7.11.7
^ permalink raw reply related
* [PATCH V2 3/5] powerpc, perf: Add new BHRB related generic functions, data and flags
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366127650-1952-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds some new BHRB related generic functions, data and flags
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/perf_event_server.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 57b42da..3f0c15c 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -33,6 +33,8 @@ struct power_pmu {
unsigned long *valp);
int (*get_alternatives)(u64 event_id, unsigned int flags,
u64 alt[]);
+ u64 (*bhrb_filter_map)(u64 branch_sample_type);
+ void (*config_bhrb)(u64 pmu_bhrb_filter);
void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
int (*limited_pmc_event)(u64 event_id);
u32 flags;
@@ -42,6 +44,9 @@ struct power_pmu {
int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+ /* BHRB entries in the PMU */
+ int bhrb_nr;
};
/*
@@ -54,6 +59,7 @@ struct power_pmu {
#define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
#define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
+#define PPMU_BHRB 0x00000080 /* has BHRB feature enabled */
/*
* Values for flags to get_alternatives()
--
1.7.11.7
^ permalink raw reply related
* [PATCH V2 0/5] powerpc, perf: BHRB based branch stack enablement on POWER8
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
Branch History Rolling Buffer (BHRB) is a new PMU feaure in IBM
POWER8 processor which records the branch instructions inside the execution
pipeline. This patchset enables the basic functionality of the feature through
generic perf branch stack sampling framework.
Sample output
-------------
$./perf record -b top
$./perf report
Overhead Command Source Shared Object Source Symbol Target Shared Object Target Symbol
# ........ ....... .................... ...................................... .................... ...................................
#
7.82% top libc-2.11.2.so [k] _IO_vfscanf libc-2.11.2.so [k] _IO_vfscanf
6.17% top libc-2.11.2.so [k] _IO_vfscanf [unknown] [k] 00000000
2.37% top [unknown] [k] 0xf7aafb30 [unknown] [k] 00000000
1.80% top [unknown] [k] 0x0fe07978 libc-2.11.2.so [k] _IO_vfscanf
1.60% top libc-2.11.2.so [k] _IO_vfscanf [kernel.kallsyms] [k] .do_task_stat
1.20% top [kernel.kallsyms] [k] .do_task_stat [kernel.kallsyms] [k] .do_task_stat
1.02% top libc-2.11.2.so [k] vfprintf libc-2.11.2.so [k] vfprintf
0.92% top top [k] _init [unknown] [k] 0x0fe037f4
Changes in V2
--------------
- Added copyright messages to the newly created files
- Modified couple of commit messages
Anshuman Khandual (5):
powerpc, perf: Add new BHRB related instructions on POWER8
powerpc, perf: Add basic assembly code to read BHRB entries on POWER8
powerpc, perf: Add new BHRB related generic functions, data and flags
powerpc, perf: Define BHRB generic functions, data and flags for POWER8
powerpc, perf: Enable branch stack sampling framework support with BHRB
arch/powerpc/include/asm/perf_event_server.h | 6 ++
arch/powerpc/include/asm/ppc-opcode.h | 7 ++
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/bhrb.S | 44 +++++++++++++
arch/powerpc/perf/core-book3s.c | 96 +++++++++++++++++++++++++++-
arch/powerpc/perf/perf_event_bhrb.c | 85 ++++++++++++++++++++++++
arch/powerpc/perf/power8-pmu.c | 57 ++++++++++++++++-
7 files changed, 292 insertions(+), 5 deletions(-)
create mode 100644 arch/powerpc/perf/bhrb.S
create mode 100644 arch/powerpc/perf/perf_event_bhrb.c
--
1.7.11.7
^ permalink raw reply
* [PATCH V2 4/5] powerpc, perf: Define BHRB generic functions, data and flags for POWER8
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366127650-1952-1-git-send-email-khandual@linux.vnet.ibm.com>
Defines BHRB functions, data and flags for POWER8
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/power8-pmu.c | 57 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 106ae0b..153408c 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -109,6 +109,16 @@
#define EVENT_IS_MARKED (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
#define EVENT_PSEL_MASK 0xff /* PMCxSEL value */
+/* MMCRA IFM bits - POWER8 */
+#define POWER8_MMCRA_IFM1 0x0000000040000000UL
+#define POWER8_MMCRA_IFM2 0x0000000080000000UL
+#define POWER8_MMCRA_IFM3 0x00000000C0000000UL
+
+#define ONLY_PLM \
+ (PERF_SAMPLE_BRANCH_USER |\
+ PERF_SAMPLE_BRANCH_KERNEL |\
+ PERF_SAMPLE_BRANCH_HV)
+
/*
* Layout of constraint bits:
*
@@ -428,6 +438,48 @@ static int power8_generic_events[] = {
[PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL,
};
+static u64 power8_bhrb_filter_map(u64 branch_sample_type)
+{
+ u64 pmu_bhrb_filter = 0;
+ u64 br_privilege = branch_sample_type & ONLY_PLM;
+
+ /* BHRB and regular PMU events share the same prvillege state
+ * filter configuration. BHRB is always recorded along with a
+ * regular PMU event. So privilege state filter criteria for BHRB
+ * and the companion PMU events has to be the same. As a default
+ * "perf record" tool sets all privillege bits ON when no filter
+ * criteria is provided in the command line. So as along as all
+ * privillege bits are ON or they are OFF, we are good to go.
+ */
+ if ((br_privilege != 7) && (br_privilege != 0))
+ return -1;
+
+ /* No branch filter requested */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
+ return pmu_bhrb_filter;
+
+ /* Invalid branch filter options - HW does not support */
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_IND_CALL)
+ return -1;
+
+ if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY_CALL) {
+ pmu_bhrb_filter |= POWER8_MMCRA_IFM1;
+ return pmu_bhrb_filter;
+ }
+
+ /* Every thing else is unsupported */
+ return -1;
+}
+
+static void power8_config_bhrb(u64 pmu_bhrb_filter)
+{
+ /* Enable BHRB filter in PMU */
+ mtspr(SPRN_MMCRA, (mfspr(SPRN_MMCRA) | pmu_bhrb_filter));
+}
+
static struct power_pmu power8_pmu = {
.name = "POWER8",
.n_counter = 6,
@@ -435,12 +487,15 @@ static struct power_pmu power8_pmu = {
.add_fields = POWER8_ADD_FIELDS,
.test_adder = POWER8_TEST_ADDER,
.compute_mmcr = power8_compute_mmcr,
+ .config_bhrb = power8_config_bhrb,
+ .bhrb_filter_map = power8_bhrb_filter_map,
.get_constraint = power8_get_constraint,
.disable_pmc = power8_disable_pmc,
- .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER,
+ .flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB,
.n_generic = ARRAY_SIZE(power8_generic_events),
.generic_events = power8_generic_events,
.attr_groups = power8_pmu_attr_groups,
+ .bhrb_nr = 32,
};
static int __init init_power8_pmu(void)
--
1.7.11.7
^ permalink raw reply related
* [PATCH V2 2/5] powerpc, perf: Add basic assembly code to read BHRB entries on POWER8
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366127650-1952-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds the basic assembly code to read BHRB entries
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/Makefile | 2 +-
arch/powerpc/perf/bhrb.S | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/perf/bhrb.S
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 472db18..510fae1 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -2,7 +2,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-$(CONFIG_PERF_EVENTS) += callchain.o
-obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o
+obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \
power5+-pmu.o power6-pmu.o power7-pmu.o \
power8-pmu.o
diff --git a/arch/powerpc/perf/bhrb.S b/arch/powerpc/perf/bhrb.S
new file mode 100644
index 0000000..0e8a018
--- /dev/null
+++ b/arch/powerpc/perf/bhrb.S
@@ -0,0 +1,44 @@
+/*
+ * Basic assembly code to read BHRB entries
+ *
+ * Copyright 2013 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/ppc_asm.h>
+#include <asm/ppc-opcode.h>
+
+ .text
+
+.balign 8
+
+/* r3 = n (where n = [0-1023])
+ * The maximum number of BHRB entries supported with PPC_MFBHRBE instruction
+ * is 1024. We have limited number of table entries here as POWER8 implements
+ * 32 BHRB entries.
+ */
+
+/* .global read_bhrb */
+_GLOBAL(read_bhrb)
+ cmpldi r3,1023
+ bgt 1f
+ ld r4,bhrb_table@got(r2)
+ sldi r3,r3,3
+ add r3,r4,r3
+ mtctr r3
+ bctr
+1: li r3,0
+ blr
+
+#define MFBHRB_TABLE1(n) PPC_MFBHRBE(R3,n); blr
+#define MFBHRB_TABLE2(n) MFBHRB_TABLE1(n); MFBHRB_TABLE1(n+1)
+#define MFBHRB_TABLE4(n) MFBHRB_TABLE2(n); MFBHRB_TABLE2(n+2)
+#define MFBHRB_TABLE8(n) MFBHRB_TABLE4(n); MFBHRB_TABLE4(n+4)
+#define MFBHRB_TABLE16(n) MFBHRB_TABLE8(n); MFBHRB_TABLE8(n+8)
+#define MFBHRB_TABLE32(n) MFBHRB_TABLE16(n); MFBHRB_TABLE16(n+16)
+
+bhrb_table:
+ MFBHRB_TABLE32(0)
--
1.7.11.7
^ permalink raw reply related
* [PATCH V2 5/5] powerpc, perf: Enable branch stack sampling framework support with BHRB
From: Anshuman Khandual @ 2013-04-16 15:54 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey
In-Reply-To: <1366127650-1952-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch provides basic enablement for perf branch stack sampling framework
on POWER8 processor with a new PMU feature called BHRB (Branch History Rolling
Buffer).
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/perf/core-book3s.c | 96 +++++++++++++++++++++++++++++++++++--
arch/powerpc/perf/perf_event_bhrb.c | 85 ++++++++++++++++++++++++++++++++
2 files changed, 178 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/perf/perf_event_bhrb.c
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4ac6e64..f4d1347 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -19,6 +19,8 @@
#include <asm/firmware.h>
#include <asm/ptrace.h>
+#define BHRB_MAX_ENTRIES 32
+
struct cpu_hw_events {
int n_events;
int n_percpu;
@@ -38,11 +40,21 @@ struct cpu_hw_events {
unsigned int group_flag;
int n_txn_start;
+
+ /* BHRB bits */
+ u64 bhrb_filter; /* BHRB HW branch filter */
+ int bhrb_users;
+ void *bhrb_context;
+ struct perf_branch_stack bhrb_stack;
+ struct perf_branch_entry bhrb_entries[BHRB_MAX_ENTRIES];
};
+
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
struct power_pmu *ppmu;
+#include "perf_event_bhrb.c"
+
/*
* Normally, to ignore kernel events we set the FCS (freeze counters
* in supervisor mode) bit in MMCR0, but if the kernel runs with the
@@ -858,6 +870,9 @@ static void power_pmu_enable(struct pmu *pmu)
}
out:
+ if (cpuhw->bhrb_users)
+ ppmu->config_bhrb(cpuhw->bhrb_filter);
+
local_irq_restore(flags);
}
@@ -888,6 +903,47 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
+/* Reset all possible BHRB entries */
+static void power_pmu_bhrb_reset(void)
+{
+ asm volatile(PPC_CLRBHRB);
+}
+
+void power_pmu_bhrb_enable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+ if (!ppmu->bhrb_nr)
+ return;
+
+ /* Clear BHRB if we changed task context to avoid data leaks */
+ if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
+ power_pmu_bhrb_reset();
+ cpuhw->bhrb_context = event->ctx;
+ }
+ cpuhw->bhrb_users++;
+}
+
+void power_pmu_bhrb_disable(struct perf_event *event)
+{
+ struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+ if (!ppmu->bhrb_nr)
+ return;
+
+ cpuhw->bhrb_users--;
+ WARN_ON_ONCE(cpuhw->bhrb_users < 0);
+
+ if (!cpuhw->disabled && !cpuhw->bhrb_users) {
+ /* BHRB cannot be turned off when other
+ * events are active on the PMU.
+ */
+
+ /* avoid stale pointer */
+ cpuhw->bhrb_context = NULL;
+ }
+}
+
/*
* Add a event to the PMU.
* If all events are not already frozen, then we disable and
@@ -947,6 +1003,9 @@ nocheck:
ret = 0;
out:
+ if (has_branch_stack(event))
+ power_pmu_bhrb_enable(event);
+
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
return ret;
@@ -999,6 +1058,9 @@ static void power_pmu_del(struct perf_event *event, int ef_flags)
cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE);
}
+ if (has_branch_stack(event))
+ power_pmu_bhrb_disable(event);
+
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
@@ -1117,6 +1179,15 @@ int power_pmu_commit_txn(struct pmu *pmu)
return 0;
}
+/* Called from ctxsw to prevent one process's branch entries to
+ * mingle with the other process's entries during context switch.
+ */
+void power_pmu_flush_branch_stack(void)
+{
+ if (ppmu->bhrb_nr)
+ power_pmu_bhrb_reset();
+}
+
/*
* Return 1 if we might be able to put event on a limited PMC,
* or 0 if not.
@@ -1231,9 +1302,11 @@ static int power_pmu_event_init(struct perf_event *event)
if (!ppmu)
return -ENOENT;
- /* does not support taken branch sampling */
- if (has_branch_stack(event))
- return -EOPNOTSUPP;
+ if (has_branch_stack(event)) {
+ /* PMU has BHRB enabled */
+ if (!(ppmu->flags & PPMU_BHRB))
+ return -EOPNOTSUPP;
+ }
switch (event->attr.type) {
case PERF_TYPE_HARDWARE:
@@ -1314,6 +1387,15 @@ static int power_pmu_event_init(struct perf_event *event)
cpuhw = &get_cpu_var(cpu_hw_events);
err = power_check_constraints(cpuhw, events, cflags, n + 1);
+
+ if (has_branch_stack(event)) {
+ cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
+ event->attr.branch_sample_type);
+
+ if(cpuhw->bhrb_filter == -1)
+ return -EOPNOTSUPP;
+ }
+
put_cpu_var(cpu_hw_events);
if (err)
return -EINVAL;
@@ -1372,6 +1454,7 @@ struct pmu power_pmu = {
.cancel_txn = power_pmu_cancel_txn,
.commit_txn = power_pmu_commit_txn,
.event_idx = power_pmu_event_idx,
+ .flush_branch_stack = power_pmu_flush_branch_stack,
};
@@ -1433,6 +1516,13 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
if (event->attr.sample_type & PERF_SAMPLE_ADDR)
perf_get_data_addr(regs, &data.addr);
+ if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) {
+ struct cpu_hw_events *cpuhw;
+ cpuhw = &__get_cpu_var(cpu_hw_events);
+ power_pmu_bhrb_read(cpuhw);
+ data.br_stack = &cpuhw->bhrb_stack;
+ }
+
if (perf_event_overflow(event, &data, regs))
power_pmu_stop(event, 0);
}
diff --git a/arch/powerpc/perf/perf_event_bhrb.c b/arch/powerpc/perf/perf_event_bhrb.c
new file mode 100644
index 0000000..961d31c
--- /dev/null
+++ b/arch/powerpc/perf/perf_event_bhrb.c
@@ -0,0 +1,85 @@
+/*
+ * Processing BHRB entries
+ *
+ * Copyright 2013 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#define BHRB_TARGET 0x0000000000000002
+#define BHRB_PREDICTION 0x0000000000000001
+#define BHRB_EA 0xFFFFFFFFFFFFFFFC
+
+extern unsigned long int read_bhrb(int n);
+
+void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
+{
+ u64 val;
+ u64 addr;
+ int r_index, u_index, target, pred;
+
+ r_index = 0;
+ u_index = 0;
+ while (r_index < ppmu->bhrb_nr) {
+ /* Assembly read function */
+ val = read_bhrb(r_index);
+
+ /* Terminal marker: End of valid BHRB entries */
+ if (val == 0) {
+ break;
+ } else {
+ /* BHRB field break up */
+ addr = val & BHRB_EA;
+ pred = val & BHRB_PREDICTION;
+ target = val & BHRB_TARGET;
+
+ /* Probable Missed entry: Not applicable for POWER8 */
+ if ((addr == 0) && (target == 0) && (pred == 1)) {
+ r_index++;
+ continue;
+ }
+
+ /* Real Missed entry: Power8 based missed entry */
+ if ((addr == 0) && (target == 1) && (pred == 1)) {
+ r_index++;
+ continue;
+ }
+
+ /* Reserved condition: Not a valid entry */
+ if ((addr == 0) && (target == 1) && (pred == 0)) {
+ r_index++;
+ continue;
+ }
+
+ /* Is a target address */
+ if (val & BHRB_TARGET) {
+ /* First address cannot be a target address */
+ if (r_index == 0) {
+ r_index++;
+ continue;
+ }
+
+ /* Update target address for the previous entry */
+ cpuhw->bhrb_entries[u_index - 1].to = addr;
+ cpuhw->bhrb_entries[u_index - 1].mispred = pred;
+ cpuhw->bhrb_entries[u_index - 1].predicted = ~pred;
+
+ /* Dont increment u_index */
+ r_index++;
+ } else {
+ /* Update address, flags for current entry */
+ cpuhw->bhrb_entries[u_index].from = addr;
+ cpuhw->bhrb_entries[u_index].mispred = pred;
+ cpuhw->bhrb_entries[u_index].predicted = ~pred;
+
+ /* Successfully popullated one entry */
+ u_index++;
+ r_index++;
+ }
+ }
+ }
+ cpuhw->bhrb_stack.nr = u_index;
+ return;
+}
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH V2 2/5] powerpc, perf: Add basic assembly code to read BHRB entries on POWER8
From: Segher Boessenkool @ 2013-04-16 17:23 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, mikey, linux-kernel
In-Reply-To: <1366127650-1952-3-git-send-email-khandual@linux.vnet.ibm.com>
> +/* r3 = n (where n = [0-1023])
> + * The maximum number of BHRB entries supported with PPC_MFBHRBE
> instruction
> + * is 1024. We have limited number of table entries here as POWER8
> implements
> + * 32 BHRB entries.
> + */
> +
> +/* .global read_bhrb */
> +_GLOBAL(read_bhrb)
> + cmpldi r3,1023
This should be 31, since that is the last entry in the table below.
> + bgt 1f
> + ld r4,bhrb_table@got(r2)
> + sldi r3,r3,3
> + add r3,r4,r3
> + mtctr r3
> + bctr
> +1: li r3,0
> + blr
> +
> +#define MFBHRB_TABLE1(n) PPC_MFBHRBE(R3,n); blr
> +#define MFBHRB_TABLE2(n) MFBHRB_TABLE1(n); MFBHRB_TABLE1(n+1)
> +#define MFBHRB_TABLE4(n) MFBHRB_TABLE2(n); MFBHRB_TABLE2(n+2)
> +#define MFBHRB_TABLE8(n) MFBHRB_TABLE4(n); MFBHRB_TABLE4(n+4)
> +#define MFBHRB_TABLE16(n) MFBHRB_TABLE8(n); MFBHRB_TABLE8(n+8)
> +#define MFBHRB_TABLE32(n) MFBHRB_TABLE16(n); MFBHRB_TABLE16(n+16)
> +
> +bhrb_table:
> + MFBHRB_TABLE32(0)
Segher
^ permalink raw reply
* [PATCH 04/28] proc: Supply PDE attribute setting accessor functions [RFC]
From: David Howells @ 2013-04-16 18:26 UTC (permalink / raw)
To: linux-kernel
Cc: alsa-devel, linux-pci, linux-wireless, netfilter-devel, viro,
netdev, linux-fsdevel, linuxppc-dev, linux-media
In-Reply-To: <20130416182550.27773.89310.stgit@warthog.procyon.org.uk>
Supply accessor functions to set attributes in proc_dir_entry structs.
The following are supplied: proc_set_size() and proc_set_user().
Signed-off-by: David Howells <dhowells@redhat.com>
cc: linuxppc-dev@lists.ozlabs.org
cc: linux-media@vger.kernel.org
cc: netdev@vger.kernel.org
cc: linux-wireless@vger.kernel.org
cc: linux-pci@vger.kernel.org
cc: netfilter-devel@vger.kernel.org
cc: alsa-devel@alsa-project.org
---
arch/powerpc/kernel/proc_powerpc.c | 2 +-
arch/powerpc/platforms/pseries/reconfig.c | 2 +-
drivers/media/pci/ttpci/av7110_ir.c | 2 +-
drivers/net/irda/vlsi_ir.c | 2 +-
drivers/net/wireless/airo.c | 34 +++++++++--------------------
drivers/pci/proc.c | 2 +-
fs/proc/generic.c | 13 +++++++++++
include/linux/proc_fs.h | 5 ++++
kernel/configs.c | 2 +-
kernel/profile.c | 2 +-
net/netfilter/xt_recent.c | 3 +--
sound/core/info.c | 2 +-
12 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c
index 41d8ee9..feb8580 100644
--- a/arch/powerpc/kernel/proc_powerpc.c
+++ b/arch/powerpc/kernel/proc_powerpc.c
@@ -83,7 +83,7 @@ static int __init proc_ppc64_init(void)
&page_map_fops, vdso_data);
if (!pde)
return 1;
- pde->size = PAGE_SIZE;
+ proc_set_size(pde, PAGE_SIZE);
return 0;
}
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index d6491bd..f93cdf5 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void)
ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
if (ent)
- ent->size = 0;
+ proc_set_size(ent, 0);
return 0;
}
diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
index eb82286..0e763a7 100644
--- a/drivers/media/pci/ttpci/av7110_ir.c
+++ b/drivers/media/pci/ttpci/av7110_ir.c
@@ -375,7 +375,7 @@ int av7110_ir_init(struct av7110 *av7110)
if (av_cnt == 1) {
e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
if (e)
- e->size = 4 + 256 * sizeof(u16);
+ proc_set_size(e, 4 + 256 * sizeof(u16));
}
tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index e22cd4e..5f47584 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1678,7 +1678,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
IRDA_WARNING("%s: failed to create proc entry\n",
__func__);
} else {
- ent->size = 0;
+ proc_set_size(ent, 0);
}
idev->proc_entry = ent;
}
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 66e398d..21d0233 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4507,73 +4507,63 @@ static int setup_proc_entry( struct net_device *dev,
airo_entry);
if (!apriv->proc_entry)
goto fail;
- apriv->proc_entry->uid = proc_kuid;
- apriv->proc_entry->gid = proc_kgid;
+ proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
/* Setup the StatsDelta */
entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
apriv->proc_entry, &proc_statsdelta_ops, dev);
if (!entry)
goto fail_stats_delta;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the Stats */
entry = proc_create_data("Stats", S_IRUGO & proc_perm,
apriv->proc_entry, &proc_stats_ops, dev);
if (!entry)
goto fail_stats;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the Status */
entry = proc_create_data("Status", S_IRUGO & proc_perm,
apriv->proc_entry, &proc_status_ops, dev);
if (!entry)
goto fail_status;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the Config */
entry = proc_create_data("Config", proc_perm,
apriv->proc_entry, &proc_config_ops, dev);
if (!entry)
goto fail_config;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the SSID */
entry = proc_create_data("SSID", proc_perm,
apriv->proc_entry, &proc_SSID_ops, dev);
if (!entry)
goto fail_ssid;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the APList */
entry = proc_create_data("APList", proc_perm,
apriv->proc_entry, &proc_APList_ops, dev);
if (!entry)
goto fail_aplist;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the BSSList */
entry = proc_create_data("BSSList", proc_perm,
apriv->proc_entry, &proc_BSSList_ops, dev);
if (!entry)
goto fail_bsslist;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
+ proc_set_user(entry, proc_kuid, proc_kgid);
/* Setup the WepKey */
entry = proc_create_data("WepKey", proc_perm,
apriv->proc_entry, &proc_wepkey_ops, dev);
if (!entry)
goto fail_wepkey;
- entry->uid = proc_kuid;
- entry->gid = proc_kgid;
-
+ proc_set_user(entry, proc_kuid, proc_kgid);
return 0;
fail_wepkey:
@@ -5695,10 +5685,8 @@ static int __init airo_init_module( void )
airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
- if (airo_entry) {
- airo_entry->uid = proc_kuid;
- airo_entry->gid = proc_kgid;
- }
+ if (airo_entry)
+ proc_set_user(airo_entry, proc_kuid, proc_kgid);
for (i = 0; i < 4 && io[i] && irq[i]; i++) {
airo_print_info("", "Trying to configure ISA adapter at irq=%d "
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 12e4fb5..7cde7c1 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -419,7 +419,7 @@ int pci_proc_attach_device(struct pci_dev *dev)
&proc_bus_pci_operations, dev);
if (!e)
return -ENOMEM;
- e->size = dev->cfg_size;
+ proc_set_size(e, dev->cfg_size);
dev->procent = e;
return 0;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 1c07cad..5f6f6c3 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -498,6 +498,19 @@ out:
return NULL;
}
EXPORT_SYMBOL(proc_create_data);
+
+void proc_set_size(struct proc_dir_entry *de, loff_t size)
+{
+ de->size = size;
+}
+EXPORT_SYMBOL(proc_set_size);
+
+void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
+{
+ de->uid = uid;
+ de->gid = gid;
+}
+EXPORT_SYMBOL(proc_set_user);
static void free_proc_entry(struct proc_dir_entry *de)
{
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 805edac..28a4d7e 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -130,6 +130,9 @@ static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,
extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
struct proc_dir_entry *parent);
+extern void proc_set_size(struct proc_dir_entry *, loff_t);
+extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t);
+
extern struct file *proc_ns_fget(int fd);
extern bool proc_ns_inode(struct inode *inode);
@@ -158,6 +161,8 @@ static inline struct proc_dir_entry *proc_mkdir(const char *name,
struct proc_dir_entry *parent) {return NULL;}
static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
umode_t mode, struct proc_dir_entry *parent) { return NULL; }
+static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {}
+static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {}
struct tty_driver;
static inline void proc_tty_register_driver(struct tty_driver *driver) {};
diff --git a/kernel/configs.c b/kernel/configs.c
index 42e8fa0..c18b1f1 100644
--- a/kernel/configs.c
+++ b/kernel/configs.c
@@ -79,7 +79,7 @@ static int __init ikconfig_init(void)
if (!entry)
return -ENOMEM;
- entry->size = kernel_config_data_size;
+ proc_set_size(entry, kernel_config_data_size);
return 0;
}
diff --git a/kernel/profile.c b/kernel/profile.c
index 524ce5e..0bf4007 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -600,7 +600,7 @@ int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */
NULL, &proc_profile_operations);
if (!entry)
return 0;
- entry->size = (1+prof_len) * sizeof(atomic_t);
+ proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t));
hotcpu_notifier(profile_cpu_callback, 0);
return 0;
}
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 3db2d38..1e657cf 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -401,8 +401,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
ret = -ENOMEM;
goto out;
}
- pde->uid = uid;
- pde->gid = gid;
+ proc_set_user(pde, uid, gid);
#endif
spin_lock_bh(&recent_lock);
list_add_tail(&t->list, &recent_net->tables);
diff --git a/sound/core/info.c b/sound/core/info.c
index 3aa8864..c7f41c3 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -970,7 +970,7 @@ int snd_info_register(struct snd_info_entry * entry)
mutex_unlock(&info_mutex);
return -ENOMEM;
}
- p->size = entry->size;
+ proc_set_size(p, entry->size);
}
entry->p = p;
if (entry->parent)
^ permalink raw reply related
* [PATCH 22/28] ppc: Clean up rtas_flash driver somewhat [RFC]
From: David Howells @ 2013-04-16 18:27 UTC (permalink / raw)
To: linux-kernel
Cc: Paul Mackerras, viro, linux-fsdevel, linuxppc-dev,
Anton Blanchard
In-Reply-To: <20130416182550.27773.89310.stgit@warthog.procyon.org.uk>
Clean up some of the problems with the rtas_flash driver:
(1) It shouldn't fiddle with the internals of the procfs filesystem (altering
pde->count).
(2) If pid namespaces are in effect, then you can get multiple inodes
connected to a single pde, thereby rendering the pde->count > 2 test
useless.
(3) The pde->count fudging doesn't work for forked, dup'd or cloned file
descriptors, so add static mutexes and use them to wrap access to the
driver through read, write and release methods.
(4) The driver can only handle one device, so allocate most of the data
previously attached to the pde->data as static variables instead (though
allocate the validation data buffer with kmalloc).
(5) We don't need to save the pde pointers as long as we have the filenames
available for removal.
(6) Don't try to multiplex what the update file read method does based on the
filename. Instead provide separate file ops and split the function.
Whilst we're at it, tabulate the procfile information and loop through it when
creating or destroying them rather than manually coding each one.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: Paul Mackerras <paulus@samba.org>
cc: Anton Blanchard <anton@samba.org>
cc: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/kernel/rtas_flash.c | 446 +++++++++++++++++---------------------
1 file changed, 200 insertions(+), 246 deletions(-)
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index c642f01..8196bfb 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -102,9 +102,10 @@ static struct kmem_cache *flash_block_cache = NULL;
#define FLASH_BLOCK_LIST_VERSION (1UL)
-/* Local copy of the flash block list.
- * We only allow one open of the flash proc file and create this
- * list as we go. The rtas_firmware_flash_list varable will be
+/*
+ * Local copy of the flash block list.
+ *
+ * The rtas_firmware_flash_list varable will be
* set once the data is fully read.
*
* For convenience as we build the list we use virtual addrs,
@@ -125,23 +126,23 @@ struct rtas_update_flash_t
struct rtas_manage_flash_t
{
int status; /* Returned status */
- unsigned int op; /* Reject or commit image */
};
/* Status int must be first member of struct */
struct rtas_validate_flash_t
{
int status; /* Returned status */
- char buf[VALIDATE_BUF_SIZE]; /* Candidate image buffer */
+ char *buf; /* Candidate image buffer */
unsigned int buf_size; /* Size of image buf */
unsigned int update_results; /* Update results token */
};
-static DEFINE_SPINLOCK(flash_file_open_lock);
-static struct proc_dir_entry *firmware_flash_pde;
-static struct proc_dir_entry *firmware_update_pde;
-static struct proc_dir_entry *validate_pde;
-static struct proc_dir_entry *manage_pde;
+static struct rtas_update_flash_t rtas_update_flash_data;
+static struct rtas_manage_flash_t rtas_manage_flash_data;
+static struct rtas_validate_flash_t rtas_validate_flash_data;
+static DEFINE_MUTEX(rtas_update_flash_mutex);
+static DEFINE_MUTEX(rtas_manage_flash_mutex);
+static DEFINE_MUTEX(rtas_validate_flash_mutex);
/* Do simple sanity checks on the flash image. */
static int flash_list_valid(struct flash_block_list *flist)
@@ -191,10 +192,10 @@ static void free_flash_list(struct flash_block_list *f)
static int rtas_flash_release(struct inode *inode, struct file *file)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_update_flash_t *uf;
-
- uf = (struct rtas_update_flash_t *) dp->data;
+ struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
+
+ mutex_lock(&rtas_update_flash_mutex);
+
if (uf->flist) {
/* File was opened in write mode for a new flash attempt */
/* Clear saved list */
@@ -214,13 +215,14 @@ static int rtas_flash_release(struct inode *inode, struct file *file)
uf->flist = NULL;
}
- atomic_dec(&dp->count);
+ mutex_unlock(&rtas_update_flash_mutex);
return 0;
}
-static void get_flash_status_msg(int status, char *buf)
+static size_t get_flash_status_msg(int status, char *buf)
{
- char *msg;
+ const char *msg;
+ size_t len;
switch (status) {
case FLASH_AUTH:
@@ -242,34 +244,51 @@ static void get_flash_status_msg(int status, char *buf)
msg = "ready: firmware image ready for flash on reboot\n";
break;
default:
- sprintf(buf, "error: unexpected status value %d\n", status);
- return;
+ return sprintf(buf, "error: unexpected status value %d\n",
+ status);
}
- strcpy(buf, msg);
+ len = strlen(msg);
+ memcpy(buf, msg, len + 1);
+ return len;
}
/* Reading the proc file will show status (not the firmware contents) */
-static ssize_t rtas_flash_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t rtas_flash_read_msg(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_update_flash_t *uf;
+ struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
char msg[RTAS_MSG_MAXLEN];
+ size_t len;
+ int status;
- uf = dp->data;
+ mutex_lock(&rtas_update_flash_mutex);
+ status = uf->status;
+ mutex_unlock(&rtas_update_flash_mutex);
- if (!strcmp(dp->name, FIRMWARE_FLASH_NAME)) {
- get_flash_status_msg(uf->status, msg);
- } else { /* FIRMWARE_UPDATE_NAME */
- sprintf(msg, "%d\n", uf->status);
- }
+ /* Read as text message */
+ len = get_flash_status_msg(uf->status, msg);
+ return simple_read_from_buffer(buf, count, ppos, msg, len);
+}
+
+static ssize_t rtas_flash_read_num(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
+ char msg[RTAS_MSG_MAXLEN];
+ int status;
+ mutex_lock(&rtas_update_flash_mutex);
+ status = uf->status;
+ mutex_unlock(&rtas_update_flash_mutex);
+
+ /* Read as number */
+ sprintf(msg, "%d\n", status);
return simple_read_from_buffer(buf, count, ppos, msg, strlen(msg));
}
/* constructor for flash_block_cache */
-void rtas_block_ctor(void *ptr)
+static void rtas_block_ctor(void *ptr)
{
memset(ptr, 0, RTAS_BLK_SIZE);
}
@@ -282,16 +301,15 @@ void rtas_block_ctor(void *ptr)
static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_update_flash_t *uf;
+ struct rtas_update_flash_t *const uf = &rtas_update_flash_data;
char *p;
- int next_free;
+ int next_free, rc;
struct flash_block_list *fl;
- uf = (struct rtas_update_flash_t *) dp->data;
+ mutex_lock(&rtas_update_flash_mutex);
if (uf->status == FLASH_AUTH || count == 0)
- return count; /* discard data */
+ goto out; /* discard data */
/* In the case that the image is not ready for flashing, the memory
* allocated for the block list will be freed upon the release of the
@@ -300,7 +318,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
if (uf->flist == NULL) {
uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
if (!uf->flist)
- return -ENOMEM;
+ goto nomem;
}
fl = uf->flist;
@@ -311,7 +329,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
/* Need to allocate another block_list */
fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
if (!fl->next)
- return -ENOMEM;
+ goto nomem;
fl = fl->next;
next_free = 0;
}
@@ -320,52 +338,37 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer,
count = RTAS_BLK_SIZE;
p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL);
if (!p)
- return -ENOMEM;
+ goto nomem;
if(copy_from_user(p, buffer, count)) {
kmem_cache_free(flash_block_cache, p);
- return -EFAULT;
+ rc = -EFAULT;
+ goto error;
}
fl->blocks[next_free].data = p;
fl->blocks[next_free].length = count;
fl->num_blocks++;
-
+out:
+ mutex_lock(&rtas_update_flash_mutex);
return count;
-}
-
-static int rtas_excl_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
-
- /* Enforce exclusive open with use count of PDE */
- spin_lock(&flash_file_open_lock);
- if (atomic_read(&dp->count) > 2) {
- spin_unlock(&flash_file_open_lock);
- return -EBUSY;
- }
-
- atomic_inc(&dp->count);
- spin_unlock(&flash_file_open_lock);
-
- return 0;
-}
-
-static int rtas_excl_release(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *dp = PDE(inode);
- atomic_dec(&dp->count);
-
- return 0;
+nomem:
+ rc = -ENOMEM;
+error:
+ mutex_lock(&rtas_update_flash_mutex);
+ return rc;
}
-static void manage_flash(struct rtas_manage_flash_t *args_buf)
+/*
+ * Flash management routines.
+ */
+static void manage_flash(struct rtas_manage_flash_t *args_buf, unsigned int op)
{
s32 rc;
do {
- rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1,
- 1, NULL, args_buf->op);
+ rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1,
+ NULL, op);
} while (rtas_busy_delay(rc));
args_buf->status = rc;
@@ -374,40 +377,38 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf)
static ssize_t manage_flash_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_manage_flash_t *args_buf;
+ struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
char msg[RTAS_MSG_MAXLEN];
- int msglen;
+ int msglen, status;
- args_buf = dp->data;
- if (args_buf == NULL)
- return 0;
-
- msglen = sprintf(msg, "%d\n", args_buf->status);
+ mutex_lock(&rtas_manage_flash_mutex);
+ status = args_buf->status;
+ mutex_unlock(&rtas_manage_flash_mutex);
+ msglen = sprintf(msg, "%d\n", status);
return simple_read_from_buffer(buf, count, ppos, msg, msglen);
}
static ssize_t manage_flash_write(struct file *file, const char __user *buf,
size_t count, loff_t *off)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_manage_flash_t *args_buf;
- const char reject_str[] = "0";
- const char commit_str[] = "1";
+ struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data;
+ static const char reject_str[] = "0";
+ static const char commit_str[] = "1";
char stkbuf[10];
- int op;
+ int op, rc;
+
+ mutex_lock(&rtas_manage_flash_mutex);
- args_buf = (struct rtas_manage_flash_t *) dp->data;
if ((args_buf->status == MANAGE_AUTH) || (count == 0))
- return count;
+ goto out;
op = -1;
if (buf) {
if (count > 9) count = 9;
- if (copy_from_user (stkbuf, buf, count)) {
- return -EFAULT;
- }
+ rc = -EFAULT;
+ if (copy_from_user (stkbuf, buf, count))
+ goto error;
if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0)
op = RTAS_REJECT_TMP_IMG;
else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0)
@@ -417,12 +418,19 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf,
if (op == -1) /* buf is empty, or contains invalid string */
return -EINVAL;
- args_buf->op = op;
- manage_flash(args_buf);
-
+ manage_flash(args_buf, op);
+out:
+ mutex_unlock(&rtas_manage_flash_mutex);
return count;
+
+error:
+ mutex_unlock(&rtas_manage_flash_mutex);
+ return rc;
}
+/*
+ * Validation routines.
+ */
static void validate_flash(struct rtas_validate_flash_t *args_buf)
{
int token = rtas_token("ibm,validate-flash-image");
@@ -462,14 +470,14 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
static ssize_t validate_flash_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_validate_flash_t *args_buf;
+ struct rtas_validate_flash_t *const args_buf =
+ &rtas_validate_flash_data;
char msg[RTAS_MSG_MAXLEN];
int msglen;
- args_buf = dp->data;
-
+ mutex_lock(&rtas_validate_flash_mutex);
msglen = get_validate_flash_msg(args_buf, msg);
+ mutex_unlock(&rtas_validate_flash_mutex);
return simple_read_from_buffer(buf, count, ppos, msg, msglen);
}
@@ -477,24 +485,18 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf,
static ssize_t validate_flash_write(struct file *file, const char __user *buf,
size_t count, loff_t *off)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_validate_flash_t *args_buf;
+ struct rtas_validate_flash_t *const args_buf =
+ &rtas_validate_flash_data;
int rc;
- args_buf = (struct rtas_validate_flash_t *) dp->data;
-
- if (dp->data == NULL) {
- dp->data = kmalloc(sizeof(struct rtas_validate_flash_t),
- GFP_KERNEL);
- if (dp->data == NULL)
- return -ENOMEM;
- }
+ mutex_lock(&rtas_validate_flash_mutex);
/* We are only interested in the first 4K of the
* candidate image */
if ((*off >= VALIDATE_BUF_SIZE) ||
(args_buf->status == VALIDATE_AUTH)) {
*off += count;
+ mutex_unlock(&rtas_validate_flash_mutex);
return count;
}
@@ -517,31 +519,29 @@ static ssize_t validate_flash_write(struct file *file, const char __user *buf,
*off += count;
rc = count;
done:
- if (rc < 0) {
- kfree(dp->data);
- dp->data = NULL;
- }
+ mutex_unlock(&rtas_validate_flash_mutex);
return rc;
}
static int validate_flash_release(struct inode *inode, struct file *file)
{
- struct proc_dir_entry *dp = PDE(file_inode(file));
- struct rtas_validate_flash_t *args_buf;
+ struct rtas_validate_flash_t *const args_buf =
+ &rtas_validate_flash_data;
- args_buf = (struct rtas_validate_flash_t *) dp->data;
+ mutex_lock(&rtas_validate_flash_mutex);
if (args_buf->status == VALIDATE_READY) {
args_buf->buf_size = VALIDATE_BUF_SIZE;
validate_flash(args_buf);
}
- /* The matching atomic_inc was in rtas_excl_open() */
- atomic_dec(&dp->count);
-
+ mutex_unlock(&rtas_validate_flash_mutex);
return 0;
}
+/*
+ * On-reboot flash update applicator.
+ */
static void rtas_flash_firmware(int reboot_type)
{
unsigned long image_size;
@@ -634,75 +634,57 @@ static void rtas_flash_firmware(int reboot_type)
spin_unlock(&rtas_data_buf_lock);
}
-static void remove_flash_pde(struct proc_dir_entry *dp)
-{
- if (dp) {
- kfree(dp->data);
- remove_proc_entry(dp->name, dp->parent);
- }
-}
-
-static int initialize_flash_pde_data(const char *rtas_call_name,
- size_t buf_size,
- struct proc_dir_entry *dp)
-{
+/*
+ * Manifest of proc files to create
+ */
+struct rtas_flash_file {
+ const char *filename;
+ const char *rtas_call_name;
int *status;
- int token;
-
- dp->data = kzalloc(buf_size, GFP_KERNEL);
- if (dp->data == NULL)
- return -ENOMEM;
-
- /*
- * This code assumes that the status int is the first member of the
- * struct
- */
- status = (int *) dp->data;
- token = rtas_token(rtas_call_name);
- if (token == RTAS_UNKNOWN_SERVICE)
- *status = FLASH_AUTH;
- else
- *status = FLASH_NO_OP;
-
- return 0;
-}
-
-static struct proc_dir_entry *create_flash_pde(const char *filename,
- const struct file_operations *fops)
-{
- return proc_create(filename, S_IRUSR | S_IWUSR, NULL, fops);
-}
-
-static const struct file_operations rtas_flash_operations = {
- .owner = THIS_MODULE,
- .read = rtas_flash_read,
- .write = rtas_flash_write,
- .open = rtas_excl_open,
- .release = rtas_flash_release,
- .llseek = default_llseek,
+ const struct file_operations fops;
};
-static const struct file_operations manage_flash_operations = {
- .owner = THIS_MODULE,
- .read = manage_flash_read,
- .write = manage_flash_write,
- .open = rtas_excl_open,
- .release = rtas_excl_release,
- .llseek = default_llseek,
-};
-
-static const struct file_operations validate_flash_operations = {
- .owner = THIS_MODULE,
- .read = validate_flash_read,
- .write = validate_flash_write,
- .open = rtas_excl_open,
- .release = validate_flash_release,
- .llseek = default_llseek,
+static const struct rtas_flash_file rtas_flash_files[] = {
+ {
+ .filename = "powerpc/rtas/" FIRMWARE_FLASH_NAME,
+ .rtas_call_name = "ibm,update-flash-64-and-reboot",
+ .status = &rtas_update_flash_data.status,
+ .fops.read = rtas_flash_read_msg,
+ .fops.write = rtas_flash_write,
+ .fops.release = rtas_flash_release,
+ .fops.llseek = default_llseek,
+ },
+ {
+ .filename = "powerpc/rtas/" FIRMWARE_UPDATE_NAME,
+ .rtas_call_name = "ibm,update-flash-64-and-reboot",
+ .status = &rtas_update_flash_data.status,
+ .fops.read = rtas_flash_read_num,
+ .fops.write = rtas_flash_write,
+ .fops.release = rtas_flash_release,
+ .fops.llseek = default_llseek,
+ },
+ {
+ .filename = "powerpc/rtas/" VALIDATE_FLASH_NAME,
+ .rtas_call_name = "ibm,validate-flash-image",
+ .status = &rtas_validate_flash_data.status,
+ .fops.read = manage_flash_read,
+ .fops.write = manage_flash_write,
+ .fops.llseek = default_llseek,
+ },
+ {
+ .filename = "powerpc/rtas/" MANAGE_FLASH_NAME,
+ .rtas_call_name = "ibm,manage-flash-image",
+ .status = &rtas_manage_flash_data.status,
+ .fops.read = validate_flash_read,
+ .fops.write = validate_flash_write,
+ .fops.release = validate_flash_release,
+ .fops.llseek = default_llseek,
+ }
};
static int __init rtas_flash_init(void)
{
- int rc;
+ int i;
if (rtas_token("ibm,update-flash-64-and-reboot") ==
RTAS_UNKNOWN_SERVICE) {
@@ -710,93 +692,65 @@ static int __init rtas_flash_init(void)
return 1;
}
- firmware_flash_pde = create_flash_pde("powerpc/rtas/"
- FIRMWARE_FLASH_NAME,
- &rtas_flash_operations);
- if (firmware_flash_pde == NULL) {
- rc = -ENOMEM;
- goto cleanup;
- }
+ rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
+ if (!rtas_validate_flash_data.buf)
+ return -ENOMEM;
- rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
- sizeof(struct rtas_update_flash_t),
- firmware_flash_pde);
- if (rc != 0)
- goto cleanup;
-
- firmware_update_pde = create_flash_pde("powerpc/rtas/"
- FIRMWARE_UPDATE_NAME,
- &rtas_flash_operations);
- if (firmware_update_pde == NULL) {
- rc = -ENOMEM;
- goto cleanup;
+ flash_block_cache = kmem_cache_create("rtas_flash_cache",
+ RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
+ rtas_block_ctor);
+ if (!flash_block_cache) {
+ printk(KERN_ERR "%s: failed to create block cache\n",
+ __func__);
+ goto enomem_buf;
}
- rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",
- sizeof(struct rtas_update_flash_t),
- firmware_update_pde);
- if (rc != 0)
- goto cleanup;
-
- validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME,
- &validate_flash_operations);
- if (validate_pde == NULL) {
- rc = -ENOMEM;
- goto cleanup;
- }
+ for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
+ const struct rtas_flash_file *f = &rtas_flash_files[i];
+ int token;
- rc = initialize_flash_pde_data("ibm,validate-flash-image",
- sizeof(struct rtas_validate_flash_t),
- validate_pde);
- if (rc != 0)
- goto cleanup;
-
- manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME,
- &manage_flash_operations);
- if (manage_pde == NULL) {
- rc = -ENOMEM;
- goto cleanup;
- }
+ if (!proc_create(f->filename, S_IRUSR | S_IWUSR, NULL, &f->fops))
+ goto enomem;
- rc = initialize_flash_pde_data("ibm,manage-flash-image",
- sizeof(struct rtas_manage_flash_t),
- manage_pde);
- if (rc != 0)
- goto cleanup;
+ /*
+ * This code assumes that the status int is the first member of the
+ * struct
+ */
+ token = rtas_token(f->rtas_call_name);
+ if (token == RTAS_UNKNOWN_SERVICE)
+ *f->status = FLASH_AUTH;
+ else
+ *f->status = FLASH_NO_OP;
+ }
rtas_flash_term_hook = rtas_flash_firmware;
-
- flash_block_cache = kmem_cache_create("rtas_flash_cache",
- RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0,
- rtas_block_ctor);
- if (!flash_block_cache) {
- printk(KERN_ERR "%s: failed to create block cache\n",
- __func__);
- rc = -ENOMEM;
- goto cleanup;
- }
return 0;
-cleanup:
- remove_flash_pde(firmware_flash_pde);
- remove_flash_pde(firmware_update_pde);
- remove_flash_pde(validate_pde);
- remove_flash_pde(manage_pde);
+enomem:
+ while (--i >= 0) {
+ const struct rtas_flash_file *f = &rtas_flash_files[i];
+ remove_proc_entry(f->filename, NULL);
+ }
- return rc;
+ kmem_cache_destroy(flash_block_cache);
+enomem_buf:
+ kfree(rtas_validate_flash_data.buf);
+ return -ENOMEM;
}
static void __exit rtas_flash_cleanup(void)
{
+ int i;
+
rtas_flash_term_hook = NULL;
- if (flash_block_cache)
- kmem_cache_destroy(flash_block_cache);
+ for (i = 0; i < ARRAY_SIZE(rtas_flash_files); i++) {
+ const struct rtas_flash_file *f = &rtas_flash_files[i];
+ remove_proc_entry(f->filename, NULL);
+ }
- remove_flash_pde(firmware_flash_pde);
- remove_flash_pde(firmware_update_pde);
- remove_flash_pde(validate_pde);
- remove_flash_pde(manage_pde);
+ kmem_cache_destroy(flash_block_cache);
+ kfree(rtas_validate_flash_data.buf);
}
module_init(rtas_flash_init);
^ permalink raw reply related
* [PATCH 23/28] ppc: Clean up scanlog [RFC]
From: David Howells @ 2013-04-16 18:27 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-fsdevel, linuxppc-dev, viro, Paul Mackerras
In-Reply-To: <20130416182550.27773.89310.stgit@warthog.procyon.org.uk>
Clean up the pseries scanlog driver's use of procfs:
(1) Don't need to save the proc_dir_entry pointer as we have the filename to
remove with.
(2) Save the scan log buffer pointer in a static variable (there is only one
of it) and don't save it in the PDE (which doesn't have a destructor).
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: Paul Mackerras <paulus@samba.org>
cc: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/platforms/pseries/scanlog.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index cc220d2..b502ab6 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -41,12 +41,12 @@
static unsigned int ibm_scan_log_dump; /* RTAS token */
-static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */
+static unsigned int *scanlog_buffer; /* The data buffer */
static ssize_t scanlog_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- unsigned int *data = PDE_DATA(file_inode(file));
+ unsigned int *data = scanlog_buffer;
int status;
unsigned long len, off;
unsigned int wait_time;
@@ -134,7 +134,7 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf,
static int scanlog_open(struct inode * inode, struct file * file)
{
- unsigned int *data = PDE_DATA(file_inode(file));
+ unsigned int *data = scanlog_buffer;
if (data[0] != 0) {
/* This imperfect test stops a second copy of the
@@ -150,10 +150,9 @@ static int scanlog_open(struct inode * inode, struct file * file)
static int scanlog_release(struct inode * inode, struct file * file)
{
- unsigned int *data = PDE_DATA(file_inode(file));
+ unsigned int *data = scanlog_buffer;
data[0] = 0;
-
return 0;
}
@@ -169,7 +168,6 @@ const struct file_operations scanlog_fops = {
static int __init scanlog_init(void)
{
struct proc_dir_entry *ent;
- void *data;
int err = -ENOMEM;
ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
@@ -177,29 +175,24 @@ static int __init scanlog_init(void)
return -ENODEV;
/* Ideally we could allocate a buffer < 4G */
- data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
- if (!data)
+ scanlog_buffer = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
+ if (!scanlog_buffer)
goto err;
- ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
- &scanlog_fops, data);
+ ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
+ &scanlog_fops);
if (!ent)
goto err;
-
- proc_ppc64_scan_log_dump = ent;
-
return 0;
err:
- kfree(data);
+ kfree(scanlog_buffer);
return err;
}
static void __exit scanlog_cleanup(void)
{
- if (proc_ppc64_scan_log_dump) {
- kfree(proc_ppc64_scan_log_dump->data);
- remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
- }
+ remove_proc_entry("powerpc/rtas/scan-log-dump", NULL);
+ kfree(scanlog_buffer);
}
module_init(scanlog_init);
^ permalink raw reply related
* Re: Build regressions/improvements in v3.9-rc7
From: Geert Uytterhoeven @ 2013-04-16 18:56 UTC (permalink / raw)
To: Linux Kernel Development; +Cc: Linux/PPC Development, linux-sh
In-Reply-To: <alpine.DEB.2.00.1304162052210.2338@ayla.of.borg>
On Tue, 16 Apr 2013, Geert Uytterhoeven wrote:
> JFYI, when comparing v3.9-rc7 to v3.9-rc6[3], the summaries are:
> - build errors: +8/-10
+ drivers/pcmcia/electra_cf.c: error: implicit declaration of function '__ioremap_at' [-Werror=implicit-function-declaration]: => 225:2
+ drivers/pcmcia/electra_cf.c: error: implicit declaration of function '__iounmap_at' [-Werror=implicit-function-declaration]: => 316:3
+ drivers/pcmcia/electra_cf.c: error: implicit declaration of function 'in_le32' [-Werror=implicit-function-declaration]: => 70:2
+ drivers/pcmcia/electra_cf.c: error: implicit declaration of function 'ioremap' [-Werror=implicit-function-declaration]: => 213:2 + drivers/pcmcia/electra_cf.c: error: implicit declaration of function 'iounmap' [-Werror=implicit-function-declaration]: => 318:3
+ drivers/pcmcia/electra_cf.c: error: implicit declaration of function 'out_le32' [-Werror=implicit-function-declaration]: => 147:2
powerpc-randconfig
> - build warnings: +164/-34
And my eye fell on this one:
+ include/math-emu/double.h: warning: "__LITTLE_ENDIAN" is not defined [-Wundef]: => 59:5
+ include/math-emu/single.h: warning: "__LITTLE_ENDIAN" is not defined [-Wundef]: => 50:5
sh-randconfig
> [1] http://kisskb.ellerman.id.au/kisskb/head/6094/ (all 118 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/6063/ (all 118 configs)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 04/28] proc: Supply PDE attribute setting accessor functions [RFC]
From: Mauro Carvalho Chehab @ 2013-04-16 21:37 UTC (permalink / raw)
To: David Howells
Cc: alsa-devel, netdev, linux-wireless, linux-kernel, netfilter-devel,
viro, linux-pci, linux-fsdevel, linuxppc-dev, linux-media
In-Reply-To: <20130416182606.27773.55054.stgit@warthog.procyon.org.uk>
Em 16-04-2013 15:26, David Howells escreveu:
> Supply accessor functions to set attributes in proc_dir_entry structs.
>
> The following are supplied: proc_set_size() and proc_set_user().
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: linuxppc-dev@lists.ozlabs.org
> cc: linux-media@vger.kernel.org
> cc: netdev@vger.kernel.org
> cc: linux-wireless@vger.kernel.org
> cc: linux-pci@vger.kernel.org
> cc: netfilter-devel@vger.kernel.org
> cc: alsa-devel@alsa-project.org
> ---
>
> arch/powerpc/kernel/proc_powerpc.c | 2 +-
> arch/powerpc/platforms/pseries/reconfig.c | 2 +-
> drivers/media/pci/ttpci/av7110_ir.c | 2 +-
Weird that av7110 IR uses /proc... Well, this is an old, obsolete driver for
hardware that is not sold anymore for a long time... So, be it.
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
> drivers/net/irda/vlsi_ir.c | 2 +-
> drivers/net/wireless/airo.c | 34 +++++++++--------------------
> drivers/pci/proc.c | 2 +-
> fs/proc/generic.c | 13 +++++++++++
> include/linux/proc_fs.h | 5 ++++
> kernel/configs.c | 2 +-
> kernel/profile.c | 2 +-
> net/netfilter/xt_recent.c | 3 +--
> sound/core/info.c | 2 +-
> 12 files changed, 38 insertions(+), 33 deletions(-)
>
> diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c
> index 41d8ee9..feb8580 100644
> --- a/arch/powerpc/kernel/proc_powerpc.c
> +++ b/arch/powerpc/kernel/proc_powerpc.c
> @@ -83,7 +83,7 @@ static int __init proc_ppc64_init(void)
> &page_map_fops, vdso_data);
> if (!pde)
> return 1;
> - pde->size = PAGE_SIZE;
> + proc_set_size(pde, PAGE_SIZE);
>
> return 0;
> }
> diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
> index d6491bd..f93cdf5 100644
> --- a/arch/powerpc/platforms/pseries/reconfig.c
> +++ b/arch/powerpc/platforms/pseries/reconfig.c
> @@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void)
>
> ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
> if (ent)
> - ent->size = 0;
> + proc_set_size(ent, 0);
>
> return 0;
> }
> diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
> index eb82286..0e763a7 100644
> --- a/drivers/media/pci/ttpci/av7110_ir.c
> +++ b/drivers/media/pci/ttpci/av7110_ir.c
> @@ -375,7 +375,7 @@ int av7110_ir_init(struct av7110 *av7110)
> if (av_cnt == 1) {
> e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
> if (e)
> - e->size = 4 + 256 * sizeof(u16);
> + proc_set_size(e, 4 + 256 * sizeof(u16));
> }
>
> tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
> diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
> index e22cd4e..5f47584 100644
> --- a/drivers/net/irda/vlsi_ir.c
> +++ b/drivers/net/irda/vlsi_ir.c
> @@ -1678,7 +1678,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> IRDA_WARNING("%s: failed to create proc entry\n",
> __func__);
> } else {
> - ent->size = 0;
> + proc_set_size(ent, 0);
> }
> idev->proc_entry = ent;
> }
> diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
> index 66e398d..21d0233 100644
> --- a/drivers/net/wireless/airo.c
> +++ b/drivers/net/wireless/airo.c
> @@ -4507,73 +4507,63 @@ static int setup_proc_entry( struct net_device *dev,
> airo_entry);
> if (!apriv->proc_entry)
> goto fail;
> - apriv->proc_entry->uid = proc_kuid;
> - apriv->proc_entry->gid = proc_kgid;
> + proc_set_user(apriv->proc_entry, proc_kuid, proc_kgid);
>
> /* Setup the StatsDelta */
> entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
> apriv->proc_entry, &proc_statsdelta_ops, dev);
> if (!entry)
> goto fail_stats_delta;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the Stats */
> entry = proc_create_data("Stats", S_IRUGO & proc_perm,
> apriv->proc_entry, &proc_stats_ops, dev);
> if (!entry)
> goto fail_stats;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the Status */
> entry = proc_create_data("Status", S_IRUGO & proc_perm,
> apriv->proc_entry, &proc_status_ops, dev);
> if (!entry)
> goto fail_status;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the Config */
> entry = proc_create_data("Config", proc_perm,
> apriv->proc_entry, &proc_config_ops, dev);
> if (!entry)
> goto fail_config;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the SSID */
> entry = proc_create_data("SSID", proc_perm,
> apriv->proc_entry, &proc_SSID_ops, dev);
> if (!entry)
> goto fail_ssid;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the APList */
> entry = proc_create_data("APList", proc_perm,
> apriv->proc_entry, &proc_APList_ops, dev);
> if (!entry)
> goto fail_aplist;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the BSSList */
> entry = proc_create_data("BSSList", proc_perm,
> apriv->proc_entry, &proc_BSSList_ops, dev);
> if (!entry)
> goto fail_bsslist;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> + proc_set_user(entry, proc_kuid, proc_kgid);
>
> /* Setup the WepKey */
> entry = proc_create_data("WepKey", proc_perm,
> apriv->proc_entry, &proc_wepkey_ops, dev);
> if (!entry)
> goto fail_wepkey;
> - entry->uid = proc_kuid;
> - entry->gid = proc_kgid;
> -
> + proc_set_user(entry, proc_kuid, proc_kgid);
> return 0;
>
> fail_wepkey:
> @@ -5695,10 +5685,8 @@ static int __init airo_init_module( void )
>
> airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
>
> - if (airo_entry) {
> - airo_entry->uid = proc_kuid;
> - airo_entry->gid = proc_kgid;
> - }
> + if (airo_entry)
> + proc_set_user(airo_entry, proc_kuid, proc_kgid);
>
> for (i = 0; i < 4 && io[i] && irq[i]; i++) {
> airo_print_info("", "Trying to configure ISA adapter at irq=%d "
> diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
> index 12e4fb5..7cde7c1 100644
> --- a/drivers/pci/proc.c
> +++ b/drivers/pci/proc.c
> @@ -419,7 +419,7 @@ int pci_proc_attach_device(struct pci_dev *dev)
> &proc_bus_pci_operations, dev);
> if (!e)
> return -ENOMEM;
> - e->size = dev->cfg_size;
> + proc_set_size(e, dev->cfg_size);
> dev->procent = e;
>
> return 0;
> diff --git a/fs/proc/generic.c b/fs/proc/generic.c
> index 1c07cad..5f6f6c3 100644
> --- a/fs/proc/generic.c
> +++ b/fs/proc/generic.c
> @@ -498,6 +498,19 @@ out:
> return NULL;
> }
> EXPORT_SYMBOL(proc_create_data);
> +
> +void proc_set_size(struct proc_dir_entry *de, loff_t size)
> +{
> + de->size = size;
> +}
> +EXPORT_SYMBOL(proc_set_size);
> +
> +void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
> +{
> + de->uid = uid;
> + de->gid = gid;
> +}
> +EXPORT_SYMBOL(proc_set_user);
>
> static void free_proc_entry(struct proc_dir_entry *de)
> {
> diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
> index 805edac..28a4d7e 100644
> --- a/include/linux/proc_fs.h
> +++ b/include/linux/proc_fs.h
> @@ -130,6 +130,9 @@ static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,
> extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
> struct proc_dir_entry *parent);
>
> +extern void proc_set_size(struct proc_dir_entry *, loff_t);
> +extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t);
> +
> extern struct file *proc_ns_fget(int fd);
> extern bool proc_ns_inode(struct inode *inode);
>
> @@ -158,6 +161,8 @@ static inline struct proc_dir_entry *proc_mkdir(const char *name,
> struct proc_dir_entry *parent) {return NULL;}
> static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
> umode_t mode, struct proc_dir_entry *parent) { return NULL; }
> +static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {}
> +static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {}
>
> struct tty_driver;
> static inline void proc_tty_register_driver(struct tty_driver *driver) {};
> diff --git a/kernel/configs.c b/kernel/configs.c
> index 42e8fa0..c18b1f1 100644
> --- a/kernel/configs.c
> +++ b/kernel/configs.c
> @@ -79,7 +79,7 @@ static int __init ikconfig_init(void)
> if (!entry)
> return -ENOMEM;
>
> - entry->size = kernel_config_data_size;
> + proc_set_size(entry, kernel_config_data_size);
>
> return 0;
> }
> diff --git a/kernel/profile.c b/kernel/profile.c
> index 524ce5e..0bf4007 100644
> --- a/kernel/profile.c
> +++ b/kernel/profile.c
> @@ -600,7 +600,7 @@ int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */
> NULL, &proc_profile_operations);
> if (!entry)
> return 0;
> - entry->size = (1+prof_len) * sizeof(atomic_t);
> + proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t));
> hotcpu_notifier(profile_cpu_callback, 0);
> return 0;
> }
> diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
> index 3db2d38..1e657cf 100644
> --- a/net/netfilter/xt_recent.c
> +++ b/net/netfilter/xt_recent.c
> @@ -401,8 +401,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
> ret = -ENOMEM;
> goto out;
> }
> - pde->uid = uid;
> - pde->gid = gid;
> + proc_set_user(pde, uid, gid);
> #endif
> spin_lock_bh(&recent_lock);
> list_add_tail(&t->list, &recent_net->tables);
> diff --git a/sound/core/info.c b/sound/core/info.c
> index 3aa8864..c7f41c3 100644
> --- a/sound/core/info.c
> +++ b/sound/core/info.c
> @@ -970,7 +970,7 @@ int snd_info_register(struct snd_info_entry * entry)
> mutex_unlock(&info_mutex);
> return -ENOMEM;
> }
> - p->size = entry->size;
> + proc_set_size(p, entry->size);
> }
> entry->p = p;
> if (entry->parent)
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: RE: [PATCH v3] clk: add PowerPC corenet clock driver support
From: Mike Turquette @ 2013-04-16 22:27 UTC (permalink / raw)
To: Tang Yuantian-B29983, Tang Yuantian-B29983
Cc: ulf.hansson@linaro.org, Li Yang-R58472, linux-doc@vger.kernel.org,
viresh.kumar@linaro.org, devicetree-discuss@lists.ozlabs.org,
linux-kernel@vger.kernel.org, shawn.guo@linaro.org,
linuxppc-dev@lists.ozlabs.org, linus.walleij@linaro.org
In-Reply-To: <D07C73A334FF604B95B3CBD2A545D07B0B144FEF@039-SN2MPN1-013.039d.mgd.msft.net>
Quoting Tang Yuantian-B29983 (2013-04-15 23:59:34)
> Hi Mike,
> =
> I really appreciate if you can spend some times to review this patch.
> =
Yauntian,
Thanks for submitting this patch. I have frozen the changes I plan to
submit for 3.10, with the exception of any last-minute fixes. I'll take
a closer look at this after the merge window.
Regards,
Mike
> Thanks,
> Yuantian
> =
> =
> > -----Original Message-----
> > From: Tang Yuantian-B29983
> > Sent: 2013=E5=B9=B44=E6=9C=889=E6=97=A5 16:46
> > To: mturquette@linaro.org
> > Cc: linus.walleij@linaro.org; viresh.kumar@linaro.org;
> > shawn.guo@linaro.org; ulf.hansson@linaro.org; linux-
> > kernel@vger.kernel.org; devicetree-discuss@lists.ozlabs.org; linuxppc-
> > dev@lists.ozlabs.org; linux-doc@vger.kernel.org; Tang Yuantian-B29983;
> > Tang Yuantian-B29983; Li Yang-R58472
> > Subject: [PATCH v3] clk: add PowerPC corenet clock driver support
> > =
> > From: Tang Yuantian <yuantian.tang@freescale.com>
> > =
> > This adds the clock driver for Freescale PowerPC corenet series SoCs
> > using common clock infrastructure.
> > =
> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > Signed-off-by: Li Yang <leoli@freescale.com>
> > ---
> > v3:
> > - remove the module author and description
> > v2:
> > - add the document for device tree clock bindings
> > =
> > arch/powerpc/platforms/Kconfig.cputype | 1 +
> > drivers/clk/Kconfig | 7 +
> > drivers/clk/Makefile | 1 +
> > drivers/clk/clk-ppc-corenet.c | 280
> > +++++++++++++++++++++++++++++++++
> > 4 files changed, 289 insertions(+)
> > create mode 100644 drivers/clk/clk-ppc-corenet.c
> > =
> > diff --git a/arch/powerpc/platforms/Kconfig.cputype
> > b/arch/powerpc/platforms/Kconfig.cputype
> > index 18e3b76..cf065b8 100644
> > --- a/arch/powerpc/platforms/Kconfig.cputype
> > +++ b/arch/powerpc/platforms/Kconfig.cputype
> > @@ -158,6 +158,7 @@ config E500
> > config PPC_E500MC
> > bool "e500mc Support"
> > select PPC_FPU
> > + select COMMON_CLK
> > depends on E500
> > help
> > This must be enabled for running on e500mc (and derivatives diff
> > --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a47e6ee..6e2fd9c
> > 100644
> > --- a/drivers/clk/Kconfig
> > +++ b/drivers/clk/Kconfig
> > @@ -63,6 +63,13 @@ config CLK_TWL6040
> > McPDM. McPDM module is using the external bit clock on the McPDM
> > bus
> > as functional clock.
> > =
> > +config CLK_PPC_CORENET
> > + bool "Clock driver for PowerPC corenet platforms"
> > + depends on PPC_E500MC && OF
> > + ---help---
> > + This adds the clock driver support for Freescale PowerPC corenet
> > + platforms using common clock framework.
> > +
> > endmenu
> > =
> > source "drivers/clk/mvebu/Kconfig"
> > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index
> > 300d477..6720319 100644
> > --- a/drivers/clk/Makefile
> > +++ b/drivers/clk/Makefile
> > @@ -34,3 +34,4 @@ obj-$(CONFIG_X86) +=3D x86/
> > obj-$(CONFIG_COMMON_CLK_WM831X) +=3D clk-wm831x.o
> > obj-$(CONFIG_COMMON_CLK_MAX77686) +=3D clk-max77686.o
> > obj-$(CONFIG_CLK_TWL6040) +=3D clk-twl6040.o
> > +obj-$(CONFIG_CLK_PPC_CORENET) +=3D clk-ppc-corenet.o
> > diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-
> > corenet.c new file mode 100644 index 0000000..a2d483f
> > --- /dev/null
> > +++ b/drivers/clk/clk-ppc-corenet.c
> > @@ -0,0 +1,280 @@
> > +/*
> > + * Copyright 2013 Freescale Semiconductor, Inc.
> > + *
> > + * 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.
> > + *
> > + * clock driver for Freescale PowerPC corenet SoCs.
> > + */
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/of.h>
> > +#include <linux/slab.h>
> > +
> > +struct cmux_clk {
> > + struct clk_hw hw;
> > + void __iomem *reg;
> > + u32 flags;
> > +};
> > +
> > +#define PLL_KILL BIT(31)
> > +#define CLKSEL_SHIFT 27
> > +#define CLKSEL_ADJUST BIT(0)
> > +#define to_cmux_clk(p) container_of(p, struct cmux_clk, =
hw)
> > +
> > +static void __iomem *base;
> > +static unsigned int clocks_per_pll;
> > +
> > +static int cmux_set_parent(struct clk_hw *hw, u8 idx) {
> > + struct cmux_clk *clk =3D to_cmux_clk(hw);
> > + u32 clksel;
> > +
> > + clksel =3D ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll;
> > + if (clk->flags & CLKSEL_ADJUST)
> > + clksel +=3D 8;
> > + clksel =3D (clksel & 0xf) << CLKSEL_SHIFT;
> > + iowrite32be(clksel, clk->reg);
> > +
> > + return 0;
> > +}
> > +
> > +static u8 cmux_get_parent(struct clk_hw *hw) {
> > + struct cmux_clk *clk =3D to_cmux_clk(hw);
> > + u32 clksel;
> > +
> > + clksel =3D ioread32be(clk->reg);
> > + clksel =3D (clksel >> CLKSEL_SHIFT) & 0xf;
> > + if (clk->flags & CLKSEL_ADJUST)
> > + clksel -=3D 8;
> > + clksel =3D (clksel >> 2) * clocks_per_pll + clksel % 4;
> > +
> > + return clksel;
> > +}
> > +
> > +const struct clk_ops cmux_ops =3D {
> > + .get_parent =3D cmux_get_parent,
> > + .set_parent =3D cmux_set_parent,
> > +};
> > +
> > +static void __init core_mux_init(struct device_node *np) {
> > + struct clk *clk;
> > + struct clk_init_data init;
> > + struct cmux_clk *cmux_clk;
> > + struct device_node *node;
> > + int rc, count, i;
> > + u32 offset;
> > + const char *clk_name;
> > + const char **parent_names;
> > +
> > + rc =3D of_property_read_u32(np, "reg", &offset);
> > + if (rc) {
> > + pr_err("%s: could not get reg property\n", np->name);
> > + return;
> > + }
> > +
> > + /* get the input clock source count */
> > + count =3D of_property_count_strings(np, "clock-names");
> > + if (count < 0) {
> > + pr_err("%s: get clock count error\n", np->name);
> > + return;
> > + }
> > + parent_names =3D kzalloc((sizeof(char *) * count), GFP_KERNEL);
> > + if (!parent_names) {
> > + pr_err("%s: could not allocate parent_names\n", __func__);
> > + return;
> > + }
> > +
> > + for (i =3D 0; i < count; i++)
> > + parent_names[i] =3D of_clk_get_parent_name(np, i);
> > +
> > + cmux_clk =3D kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
> > + if (!cmux_clk) {
> > + pr_err("%s: could not allocate cmux_clk\n", __func__);
> > + goto err_name;
> > + }
> > + cmux_clk->reg =3D base + offset;
> > +
> > + node =3D of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen"=
);
> > + if (node && (offset >=3D 0x80))
> > + cmux_clk->flags =3D CLKSEL_ADJUST;
> > +
> > + rc =3D of_property_read_string_index(np, "clock-output-names",
> > + 0, &clk_name);
> > + if (rc) {
> > + pr_err("%s: read clock names error\n", np->name);
> > + goto err_clk;
> > + }
> > +
> > + init.name =3D clk_name;
> > + init.ops =3D &cmux_ops;
> > + init.parent_names =3D parent_names;
> > + init.num_parents =3D count;
> > + init.flags =3D 0;
> > + cmux_clk->hw.init =3D &init;
> > +
> > + clk =3D clk_register(NULL, &cmux_clk->hw);
> > + if (IS_ERR(clk)) {
> > + pr_err("%s: could not register clock\n", clk_name);
> > + goto err_clk;
> > + }
> > +
> > + rc =3D of_clk_add_provider(np, of_clk_src_simple_get, clk);
> > + if (rc) {
> > + pr_err("Could not register clock provider for node:%s\n",
> > + np->name);
> > + goto err_clk;
> > + }
> > + goto err_name;
> > +
> > +err_clk:
> > + kfree(cmux_clk);
> > +err_name:
> > + /* free *_names because they are reallocated when registered */
> > + kfree(parent_names);
> > +}
> > +
> > +static void __init core_pll_init(struct device_node *np) {
> > + u32 offset, mult;
> > + int i, rc, count;
> > + const char *clk_name, *parent_name;
> > + struct clk_onecell_data *onecell_data;
> > + struct clk **subclks;
> > +
> > + rc =3D of_property_read_u32(np, "reg", &offset);
> > + if (rc) {
> > + pr_err("%s: could not get reg property\n", np->name);
> > + return;
> > + }
> > +
> > + /* get the multiple of PLL */
> > + mult =3D ioread32be(base + offset);
> > +
> > + /* check if this PLL is disabled */
> > + if (mult & PLL_KILL) {
> > + pr_debug("PLL:%s is disabled\n", np->name);
> > + return;
> > + }
> > + mult =3D (mult >> 1) & 0x3f;
> > +
> > + parent_name =3D of_clk_get_parent_name(np, 0);
> > + if (!parent_name) {
> > + pr_err("PLL: %s must have a parent\n", np->name);
> > + return;
> > + }
> > +
> > + count =3D of_property_count_strings(np, "clock-output-names");
> > + if (count < 0 || count > 4) {
> > + pr_err("%s: clock is not supported\n", np->name);
> > + return;
> > + }
> > +
> > + /* output clock number per PLL */
> > + clocks_per_pll =3D count;
> > +
> > + subclks =3D kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
> > + if (!subclks) {
> > + pr_err("%s: could not allocate subclks\n", __func__);
> > + return;
> > + }
> > +
> > + onecell_data =3D kzalloc(sizeof(struct clk_onecell_data), GFP_KER=
NEL);
> > + if (!onecell_data) {
> > + pr_err("%s: could not allocate onecell_data\n", __func__);
> > + goto err_clks;
> > + }
> > +
> > + for (i =3D 0; i < count; i++) {
> > + rc =3D of_property_read_string_index(np, "clock-output-na=
mes",
> > + i, &clk_name);
> > + if (rc) {
> > + pr_err("%s: could not get clock names\n", np->nam=
e);
> > + goto err_cell;
> > + }
> > +
> > + /*
> > + * when count =3D=3D 4, there are 4 output clocks:
> > + * /1, /2, /3, /4 respectively
> > + * when count < 4, there are at least 2 output clocks:
> > + * /1, /2, (/4, if count =3D=3D 3) respectively.
> > + */
> > + if (count =3D=3D 4)
> > + subclks[i] =3D clk_register_fixed_factor(NULL, cl=
k_name,
> > + parent_name, 0, mult, 1 + i);
> > + else
> > +
> > + subclks[i] =3D clk_register_fixed_factor(NULL, cl=
k_name,
> > + parent_name, 0, mult, 1 << i);
> > +
> > + if (IS_ERR(subclks[i])) {
> > + pr_err("%s: could not register clock\n", clk_name=
);
> > + goto err_cell;
> > + }
> > + }
> > +
> > + onecell_data->clks =3D subclks;
> > + onecell_data->clk_num =3D count;
> > +
> > + rc =3D of_clk_add_provider(np, of_clk_src_onecell_get, onecell_da=
ta);
> > + if (rc) {
> > + pr_err("Could not register clk provider for node:%s\n",
> > + np->name);
> > + goto err_cell;
> > + }
> > +
> > + return;
> > +err_cell:
> > + kfree(onecell_data);
> > +err_clks:
> > + kfree(subclks);
> > +}
> > +
> > +static const struct of_device_id clk_match[] __initconst =3D {
> > + { .compatible =3D "fixed-clock", .data =3D of_fixed_clk_setup, },
> > + { .compatible =3D "fsl,core-pll-clock", .data =3D core_pll_init, =
},
> > + { .compatible =3D "fsl,core-mux-clock", .data =3D core_mux_init, =
},
> > + {}
> > +};
> > +
> > +static int __init ppc_corenet_clk_probe(struct platform_device *pdev) {
> > + struct device_node *np;
> > +
> > + np =3D pdev->dev.of_node;
> > + base =3D of_iomap(np, 0);
> > + if (!base) {
> > + dev_err(&pdev->dev, "iomap error\n");
> > + return -ENOMEM;
> > + }
> > + of_clk_init(clk_match);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id ppc_clk_ids[] __initconst =3D {
> > + { .compatible =3D "fsl,qoriq-clockgen-1.0", },
> > + { .compatible =3D "fsl,qoriq-clockgen-2", },
> > + {}
> > +};
> > +
> > +static struct platform_driver ppc_corenet_clk_driver =3D {
> > + .driver =3D {
> > + .name =3D "ppc_corenet_clock",
> > + .owner =3D THIS_MODULE,
> > + .of_match_table =3D ppc_clk_ids,
> > + },
> > + .probe =3D ppc_corenet_clk_probe,
> > +};
> > +
> > +static int __init ppc_corenet_clk_init(void) {
> > + return platform_driver_register(&ppc_corenet_clk_driver);
> > +}
> > +subsys_initcall(ppc_corenet_clk_init);
> > --
> > 1.8.0
^ permalink raw reply
* Re: [PATCH v3 1/4] powerpc/mpic: add irq_set_wake support
From: Scott Wood @ 2013-04-16 23:30 UTC (permalink / raw)
To: Wang Dongsheng-B40534; +Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F15439259EE77D8@039-SN2MPN1-021.039d.mgd.msft.net>
ACK
-Scott
On 04/16/2013 05:58:52 AM, Wang Dongsheng-B40534 wrote:
> Hi scott,
>=20
> Could you ACK these patches?
>=20
> [PATCH v3 2/4] powerpc/mpic: add global timer support
> [PATCH v3 3/4] powerpc/mpic: create mpic subsystem object
> [PATCH v3 4/4] powerpc/fsl: add MPIC timer wakeup support
>=20
> Thanks.
>=20
> > -----Original Message-----
> > From: Wang Dongsheng-B40534
> > Sent: Tuesday, April 09, 2013 10:22 AM
> > To: Wood Scott-B07421
> > Cc: linuxppc-dev@lists.ozlabs.org; Wang Dongsheng-B40534
> > Subject: [PATCH v3 1/4] powerpc/mpic: add irq_set_wake support
> >
> > Add irq_set_wake support. Just add IRQF_NO_SUSPEND to =20
> desc->action->flag.
> > So the wake up interrupt will not be disable in suspend_device_irqs.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> > ---
> > v3:
> > * Modify: Change "EINVAL" to "ENXIO" in mpic_irq_set_wake()
> >
> > v2:
> > * Add: Check freescale chip in mpic_irq_set_wake().
> > * Remove: Support mpic_irq_set_wake() in ht_chip.
> >
> > arch/powerpc/sysdev/mpic.c | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> >
> > diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> > index 3b2efd4..ae709d2 100644
> > --- a/arch/powerpc/sysdev/mpic.c
> > +++ b/arch/powerpc/sysdev/mpic.c
> > @@ -920,6 +920,22 @@ int mpic_set_irq_type(struct irq_data *d, =20
> unsigned
> > int flow_type)
> > return IRQ_SET_MASK_OK_NOCOPY;
> > }
> >
> > +static int mpic_irq_set_wake(struct irq_data *d, unsigned int on) {
> > + struct irq_desc *desc =3D container_of(d, struct irq_desc, =20
> irq_data);
> > + struct mpic *mpic =3D mpic_from_irq_data(d);
> > +
> > + if (!(mpic->flags & MPIC_FSL))
> > + return -ENXIO;
> > +
> > + if (on)
> > + desc->action->flags |=3D IRQF_NO_SUSPEND;
> > + else
> > + desc->action->flags &=3D ~IRQF_NO_SUSPEND;
> > +
> > + return 0;
> > +}
> > +
> > void mpic_set_vector(unsigned int virq, unsigned int vector) {
> > struct mpic *mpic =3D mpic_from_irq(virq); @@ -957,6 +973,7 @@ =20
> static
> > struct irq_chip mpic_irq_chip =3D {
> > .irq_unmask =3D mpic_unmask_irq,
> > .irq_eoi =3D mpic_end_irq,
> > .irq_set_type =3D mpic_set_irq_type,
> > + .irq_set_wake =3D mpic_irq_set_wake,
> > };
> >
> > #ifdef CONFIG_SMP
> > @@ -971,6 +988,7 @@ static struct irq_chip mpic_tm_chip =3D {
> > .irq_mask =3D mpic_mask_tm,
> > .irq_unmask =3D mpic_unmask_tm,
> > .irq_eoi =3D mpic_end_irq,
> > + .irq_set_wake =3D mpic_irq_set_wake,
> > };
> >
> > #ifdef CONFIG_MPIC_U3_HT_IRQS
> > --
> > 1.8.0
>=20
>=20
>=20
=
^ permalink raw reply
* RE: RE: [PATCH v3] clk: add PowerPC corenet clock driver support
From: Tang Yuantian-B29983 @ 2013-04-17 2:12 UTC (permalink / raw)
To: Mike Turquette
Cc: ulf.hansson@linaro.org, Li Yang-R58472, linux-doc@vger.kernel.org,
viresh.kumar@linaro.org, devicetree-discuss@lists.ozlabs.org,
linux-kernel@vger.kernel.org, shawn.guo@linaro.org,
linuxppc-dev@lists.ozlabs.org, linus.walleij@linaro.org
In-Reply-To: <20130416222721.19887.3395@quantum>
T0ssIHRoYW5rcy4NCg0KVGhhbmtzLA0KWXVhbnRpYW4NCg0KDQo+IC0tLS0tT3JpZ2luYWwgTWVz
c2FnZS0tLS0tDQo+IEZyb206IE1pa2UgVHVycXVldHRlIFttYWlsdG86bXR1cnF1ZXR0ZUBsaW5h
cm8ub3JnXQ0KPiBTZW50OiAyMDEz5bm0NOaciDE35pelIDY6MjcNCj4gVG86IFRhbmcgWXVhbnRp
YW4tQjI5OTgzOyBUYW5nIFl1YW50aWFuLUIyOTk4Mw0KPiBDYzogbGludXMud2FsbGVpakBsaW5h
cm8ub3JnOyB2aXJlc2gua3VtYXJAbGluYXJvLm9yZzsNCj4gc2hhd24uZ3VvQGxpbmFyby5vcmc7
IHVsZi5oYW5zc29uQGxpbmFyby5vcmc7IGxpbnV4LQ0KPiBrZXJuZWxAdmdlci5rZXJuZWwub3Jn
OyBkZXZpY2V0cmVlLWRpc2N1c3NAbGlzdHMub3psYWJzLm9yZzsgbGludXhwcGMtDQo+IGRldkBs
aXN0cy5vemxhYnMub3JnOyBsaW51eC1kb2NAdmdlci5rZXJuZWwub3JnOyBMaSBZYW5nLVI1ODQ3
Mg0KPiBTdWJqZWN0OiBSZTogUkU6IFtQQVRDSCB2M10gY2xrOiBhZGQgUG93ZXJQQyBjb3JlbmV0
IGNsb2NrIGRyaXZlciBzdXBwb3J0DQo+IA0KPiBRdW90aW5nIFRhbmcgWXVhbnRpYW4tQjI5OTgz
ICgyMDEzLTA0LTE1IDIzOjU5OjM0KQ0KPiA+IEhpIE1pa2UsDQo+ID4NCj4gPiBJIHJlYWxseSBh
cHByZWNpYXRlIGlmIHlvdSBjYW4gc3BlbmQgc29tZSB0aW1lcyB0byByZXZpZXcgdGhpcyBwYXRj
aC4NCj4gPg0KPiANCj4gWWF1bnRpYW4sDQo+IA0KPiBUaGFua3MgZm9yIHN1Ym1pdHRpbmcgdGhp
cyBwYXRjaC4gIEkgaGF2ZSBmcm96ZW4gdGhlIGNoYW5nZXMgSSBwbGFuIHRvDQo+IHN1Ym1pdCBm
b3IgMy4xMCwgd2l0aCB0aGUgZXhjZXB0aW9uIG9mIGFueSBsYXN0LW1pbnV0ZSBmaXhlcy4gIEkn
bGwgdGFrZQ0KPiBhIGNsb3NlciBsb29rIGF0IHRoaXMgYWZ0ZXIgdGhlIG1lcmdlIHdpbmRvdy4N
Cj4gDQo+IFJlZ2FyZHMsDQo+IE1pa2UNCj4gDQo+ID4gVGhhbmtzLA0KPiA+IFl1YW50aWFuDQo+
ID4NCj4gPg0KPiA+ID4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPiA+IEZyb206IFRh
bmcgWXVhbnRpYW4tQjI5OTgzDQo+ID4gPiBTZW50OiAyMDEz5bm0NOaciDnml6UgMTY6NDYNCj4g
PiA+IFRvOiBtdHVycXVldHRlQGxpbmFyby5vcmcNCj4gPiA+IENjOiBsaW51cy53YWxsZWlqQGxp
bmFyby5vcmc7IHZpcmVzaC5rdW1hckBsaW5hcm8ub3JnOw0KPiA+ID4gc2hhd24uZ3VvQGxpbmFy
by5vcmc7IHVsZi5oYW5zc29uQGxpbmFyby5vcmc7IGxpbnV4LQ0KPiA+ID4ga2VybmVsQHZnZXIu
a2VybmVsLm9yZzsgZGV2aWNldHJlZS1kaXNjdXNzQGxpc3RzLm96bGFicy5vcmc7DQo+ID4gPiBs
aW51eHBwYy0gZGV2QGxpc3RzLm96bGFicy5vcmc7IGxpbnV4LWRvY0B2Z2VyLmtlcm5lbC5vcmc7
IFRhbmcNCj4gPiA+IFl1YW50aWFuLUIyOTk4MzsgVGFuZyBZdWFudGlhbi1CMjk5ODM7IExpIFlh
bmctUjU4NDcyDQo+ID4gPiBTdWJqZWN0OiBbUEFUQ0ggdjNdIGNsazogYWRkIFBvd2VyUEMgY29y
ZW5ldCBjbG9jayBkcml2ZXIgc3VwcG9ydA0KPiA+ID4NCj4gPiA+IEZyb206IFRhbmcgWXVhbnRp
YW4gPHl1YW50aWFuLnRhbmdAZnJlZXNjYWxlLmNvbT4NCj4gPiA+DQo+ID4gPiBUaGlzIGFkZHMg
dGhlIGNsb2NrIGRyaXZlciBmb3IgRnJlZXNjYWxlIFBvd2VyUEMgY29yZW5ldCBzZXJpZXMgU29D
cw0KPiA+ID4gdXNpbmcgY29tbW9uIGNsb2NrIGluZnJhc3RydWN0dXJlLg0KPiA+ID4NCj4gPiA+
IFNpZ25lZC1vZmYtYnk6IFRhbmcgWXVhbnRpYW4gPFl1YW50aWFuLlRhbmdAZnJlZXNjYWxlLmNv
bT4NCj4gPiA+IFNpZ25lZC1vZmYtYnk6IExpIFlhbmcgPGxlb2xpQGZyZWVzY2FsZS5jb20+DQo+
ID4gPiAtLS0NCj4gPiA+IHYzOg0KPiA+ID4gICAgICAgLSByZW1vdmUgdGhlIG1vZHVsZSBhdXRo
b3IgYW5kIGRlc2NyaXB0aW9uDQo+ID4gPiB2MjoNCj4gPiA+ICAgICAgIC0gYWRkIHRoZSBkb2N1
bWVudCBmb3IgZGV2aWNlIHRyZWUgY2xvY2sgYmluZGluZ3MNCj4gPiA+DQo+ID4gPiAgYXJjaC9w
b3dlcnBjL3BsYXRmb3Jtcy9LY29uZmlnLmNwdXR5cGUgfCAgIDEgKw0KPiA+ID4gIGRyaXZlcnMv
Y2xrL0tjb25maWcgICAgICAgICAgICAgICAgICAgIHwgICA3ICsNCj4gPiA+ICBkcml2ZXJzL2Ns
ay9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICB8ICAgMSArDQo+ID4gPiAgZHJpdmVycy9jbGsv
Y2xrLXBwYy1jb3JlbmV0LmMgICAgICAgICAgfCAyODANCj4gPiA+ICsrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKw0KPiA+ID4gIDQgZmlsZXMgY2hhbmdlZCwgMjg5IGluc2VydGlvbnMo
KykNCj4gPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvY2xrLXBwYy1jb3JlbmV0
LmMNCj4gPiA+DQo+ID4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy9LY29u
ZmlnLmNwdXR5cGUNCj4gPiA+IGIvYXJjaC9wb3dlcnBjL3BsYXRmb3Jtcy9LY29uZmlnLmNwdXR5
cGUNCj4gPiA+IGluZGV4IDE4ZTNiNzYuLmNmMDY1YjggMTAwNjQ0DQo+ID4gPiAtLS0gYS9hcmNo
L3Bvd2VycGMvcGxhdGZvcm1zL0tjb25maWcuY3B1dHlwZQ0KPiA+ID4gKysrIGIvYXJjaC9wb3dl
cnBjL3BsYXRmb3Jtcy9LY29uZmlnLmNwdXR5cGUNCj4gPiA+IEBAIC0xNTgsNiArMTU4LDcgQEAg
Y29uZmlnIEU1MDANCj4gPiA+ICBjb25maWcgUFBDX0U1MDBNQw0KPiA+ID4gICAgICAgYm9vbCAi
ZTUwMG1jIFN1cHBvcnQiDQo+ID4gPiAgICAgICBzZWxlY3QgUFBDX0ZQVQ0KPiA+ID4gKyAgICAg
c2VsZWN0IENPTU1PTl9DTEsNCj4gPiA+ICAgICAgIGRlcGVuZHMgb24gRTUwMA0KPiA+ID4gICAg
ICAgaGVscA0KPiA+ID4gICAgICAgICBUaGlzIG11c3QgYmUgZW5hYmxlZCBmb3IgcnVubmluZyBv
biBlNTAwbWMgKGFuZCBkZXJpdmF0aXZlcw0KPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xr
L0tjb25maWcgYi9kcml2ZXJzL2Nsay9LY29uZmlnIGluZGV4DQo+ID4gPiBhNDdlNmVlLi42ZTJm
ZDljDQo+ID4gPiAxMDA2NDQNCj4gPiA+IC0tLSBhL2RyaXZlcnMvY2xrL0tjb25maWcNCj4gPiA+
ICsrKyBiL2RyaXZlcnMvY2xrL0tjb25maWcNCj4gPiA+IEBAIC02Myw2ICs2MywxMyBAQCBjb25m
aWcgQ0xLX1RXTDYwNDANCj4gPiA+ICAgICAgICAgTWNQRE0uIE1jUERNIG1vZHVsZSBpcyB1c2lu
ZyB0aGUgZXh0ZXJuYWwgYml0IGNsb2NrIG9uIHRoZQ0KPiA+ID4gTWNQRE0gYnVzDQo+ID4gPiAg
ICAgICAgIGFzIGZ1bmN0aW9uYWwgY2xvY2suDQo+ID4gPg0KPiA+ID4gK2NvbmZpZyBDTEtfUFBD
X0NPUkVORVQNCj4gPiA+ICsgICAgIGJvb2wgIkNsb2NrIGRyaXZlciBmb3IgUG93ZXJQQyBjb3Jl
bmV0IHBsYXRmb3JtcyINCj4gPiA+ICsgICAgIGRlcGVuZHMgb24gUFBDX0U1MDBNQyAmJiBPRg0K
PiA+ID4gKyAgICAgLS0taGVscC0tLQ0KPiA+ID4gKyAgICAgICBUaGlzIGFkZHMgdGhlIGNsb2Nr
IGRyaXZlciBzdXBwb3J0IGZvciBGcmVlc2NhbGUgUG93ZXJQQw0KPiBjb3JlbmV0DQo+ID4gPiAr
ICAgICAgIHBsYXRmb3JtcyB1c2luZyBjb21tb24gY2xvY2sgZnJhbWV3b3JrLg0KPiA+ID4gKw0K
PiA+ID4gIGVuZG1lbnUNCj4gPiA+DQo+ID4gPiAgc291cmNlICJkcml2ZXJzL2Nsay9tdmVidS9L
Y29uZmlnIg0KPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xrL01ha2VmaWxlIGIvZHJpdmVy
cy9jbGsvTWFrZWZpbGUgaW5kZXgNCj4gPiA+IDMwMGQ0NzcuLjY3MjAzMTkgMTAwNjQ0DQo+ID4g
PiAtLS0gYS9kcml2ZXJzL2Nsay9NYWtlZmlsZQ0KPiA+ID4gKysrIGIvZHJpdmVycy9jbGsvTWFr
ZWZpbGUNCj4gPiA+IEBAIC0zNCwzICszNCw0IEBAIG9iai0kKENPTkZJR19YODYpICAgICAgICAg
ICArPSB4ODYvDQo+ID4gPiAgb2JqLSQoQ09ORklHX0NPTU1PTl9DTEtfV004MzFYKSArPSBjbGst
d204MzF4Lm8NCj4gPiA+ICBvYmotJChDT05GSUdfQ09NTU9OX0NMS19NQVg3NzY4NikgKz0gY2xr
LW1heDc3Njg2Lm8NCj4gPiA+ICBvYmotJChDT05GSUdfQ0xLX1RXTDYwNDApICAgICs9IGNsay10
d2w2MDQwLm8NCj4gPiA+ICtvYmotJChDT05GSUdfQ0xLX1BQQ19DT1JFTkVUKSAgICAgICAgKz0g
Y2xrLXBwYy1jb3JlbmV0Lm8NCj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nsay9jbGstcHBj
LWNvcmVuZXQuYyBiL2RyaXZlcnMvY2xrL2Nsay1wcGMtDQo+ID4gPiBjb3JlbmV0LmMgbmV3IGZp
bGUgbW9kZSAxMDA2NDQgaW5kZXggMDAwMDAwMC4uYTJkNDgzZg0KPiA+ID4gLS0tIC9kZXYvbnVs
bA0KPiA+ID4gKysrIGIvZHJpdmVycy9jbGsvY2xrLXBwYy1jb3JlbmV0LmMNCj4gPiA+IEBAIC0w
LDAgKzEsMjgwIEBADQo+ID4gPiArLyoNCj4gPiA+ICsgKiBDb3B5cmlnaHQgMjAxMyBGcmVlc2Nh
bGUgU2VtaWNvbmR1Y3RvciwgSW5jLg0KPiA+ID4gKyAqDQo+ID4gPiArICogVGhpcyBwcm9ncmFt
IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcg0KPiA+ID4g
K21vZGlmeQ0KPiA+ID4gKyAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwg
UHVibGljIExpY2Vuc2UgdmVyc2lvbiAyDQo+ID4gPiArYXMNCj4gPiA+ICsgKiBwdWJsaXNoZWQg
YnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4NCj4gPiA+ICsgKg0KPiA+ID4gKyAqIGNs
b2NrIGRyaXZlciBmb3IgRnJlZXNjYWxlIFBvd2VyUEMgY29yZW5ldCBTb0NzLg0KPiA+ID4gKyAq
Lw0KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9jbGstcHJvdmlkZXIuaD4NCj4gPiA+ICsjaW5jbHVk
ZSA8bGludXgvaW8uaD4NCj4gPiA+ICsjaW5jbHVkZSA8bGludXgva2VybmVsLmg+DQo+ID4gPiAr
I2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9vZl9wbGF0
Zm9ybS5oPg0KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiA+ID4gKyNpbmNsdWRlIDxs
aW51eC9zbGFiLmg+DQo+ID4gPiArDQo+ID4gPiArc3RydWN0IGNtdXhfY2xrIHsNCj4gPiA+ICsg
ICAgIHN0cnVjdCBjbGtfaHcgaHc7DQo+ID4gPiArICAgICB2b2lkIF9faW9tZW0gKnJlZzsNCj4g
PiA+ICsgICAgIHUzMiBmbGFnczsNCj4gPiA+ICt9Ow0KPiA+ID4gKw0KPiA+ID4gKyNkZWZpbmUg
UExMX0tJTEwgICAgICAgICAgICAgICAgICAgICBCSVQoMzEpDQo+ID4gPiArI2RlZmluZSAgICAg
IENMS1NFTF9TSElGVCAgICAgICAgICAgIDI3DQo+ID4gPiArI2RlZmluZSBDTEtTRUxfQURKVVNU
ICAgICAgICAgICAgICAgIEJJVCgwKQ0KPiA+ID4gKyNkZWZpbmUgdG9fY211eF9jbGsocCkgICAg
ICAgICAgICAgICBjb250YWluZXJfb2YocCwgc3RydWN0IGNtdXhfY2xrLA0KPiBodykNCj4gPiA+
ICsNCj4gPiA+ICtzdGF0aWMgdm9pZCBfX2lvbWVtICpiYXNlOw0KPiA+ID4gK3N0YXRpYyB1bnNp
Z25lZCBpbnQgY2xvY2tzX3Blcl9wbGw7DQo+ID4gPiArDQo+ID4gPiArc3RhdGljIGludCBjbXV4
X3NldF9wYXJlbnQoc3RydWN0IGNsa19odyAqaHcsIHU4IGlkeCkgew0KPiA+ID4gKyAgICAgc3Ry
dWN0IGNtdXhfY2xrICpjbGsgPSB0b19jbXV4X2Nsayhodyk7DQo+ID4gPiArICAgICB1MzIgY2xr
c2VsOw0KPiA+ID4gKw0KPiA+ID4gKyAgICAgY2xrc2VsID0gKChpZHggLyBjbG9ja3NfcGVyX3Bs
bCkgPDwgMikgKyBpZHggJSBjbG9ja3NfcGVyX3BsbDsNCj4gPiA+ICsgICAgIGlmIChjbGstPmZs
YWdzICYgQ0xLU0VMX0FESlVTVCkNCj4gPiA+ICsgICAgICAgICAgICAgY2xrc2VsICs9IDg7DQo+
ID4gPiArICAgICBjbGtzZWwgPSAoY2xrc2VsICYgMHhmKSA8PCBDTEtTRUxfU0hJRlQ7DQo+ID4g
PiArICAgICBpb3dyaXRlMzJiZShjbGtzZWwsIGNsay0+cmVnKTsNCj4gPiA+ICsNCj4gPiA+ICsg
ICAgIHJldHVybiAwOw0KPiA+ID4gK30NCj4gPiA+ICsNCj4gPiA+ICtzdGF0aWMgdTggY211eF9n
ZXRfcGFyZW50KHN0cnVjdCBjbGtfaHcgKmh3KSB7DQo+ID4gPiArICAgICBzdHJ1Y3QgY211eF9j
bGsgKmNsayA9IHRvX2NtdXhfY2xrKGh3KTsNCj4gPiA+ICsgICAgIHUzMiBjbGtzZWw7DQo+ID4g
PiArDQo+ID4gPiArICAgICBjbGtzZWwgPSBpb3JlYWQzMmJlKGNsay0+cmVnKTsNCj4gPiA+ICsg
ICAgIGNsa3NlbCA9IChjbGtzZWwgPj4gQ0xLU0VMX1NISUZUKSAmIDB4ZjsNCj4gPiA+ICsgICAg
IGlmIChjbGstPmZsYWdzICYgQ0xLU0VMX0FESlVTVCkNCj4gPiA+ICsgICAgICAgICAgICAgY2xr
c2VsIC09IDg7DQo+ID4gPiArICAgICBjbGtzZWwgPSAoY2xrc2VsID4+IDIpICogY2xvY2tzX3Bl
cl9wbGwgKyBjbGtzZWwgJSA0Ow0KPiA+ID4gKw0KPiA+ID4gKyAgICAgcmV0dXJuIGNsa3NlbDsN
Cj4gPiA+ICt9DQo+ID4gPiArDQo+ID4gPiArY29uc3Qgc3RydWN0IGNsa19vcHMgY211eF9vcHMg
PSB7DQo+ID4gPiArICAgICAuZ2V0X3BhcmVudCA9IGNtdXhfZ2V0X3BhcmVudCwNCj4gPiA+ICsg
ICAgIC5zZXRfcGFyZW50ID0gY211eF9zZXRfcGFyZW50LCB9Ow0KPiA+ID4gKw0KPiA+ID4gK3N0
YXRpYyB2b2lkIF9faW5pdCBjb3JlX211eF9pbml0KHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnApIHsN
Cj4gPiA+ICsgICAgIHN0cnVjdCBjbGsgKmNsazsNCj4gPiA+ICsgICAgIHN0cnVjdCBjbGtfaW5p
dF9kYXRhIGluaXQ7DQo+ID4gPiArICAgICBzdHJ1Y3QgY211eF9jbGsgKmNtdXhfY2xrOw0KPiA+
ID4gKyAgICAgc3RydWN0IGRldmljZV9ub2RlICpub2RlOw0KPiA+ID4gKyAgICAgaW50IHJjLCBj
b3VudCwgaTsNCj4gPiA+ICsgICAgIHUzMiAgICAgb2Zmc2V0Ow0KPiA+ID4gKyAgICAgY29uc3Qg
Y2hhciAqY2xrX25hbWU7DQo+ID4gPiArICAgICBjb25zdCBjaGFyICoqcGFyZW50X25hbWVzOw0K
PiA+ID4gKw0KPiA+ID4gKyAgICAgcmMgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgInJlZyIs
ICZvZmZzZXQpOw0KPiA+ID4gKyAgICAgaWYgKHJjKSB7DQo+ID4gPiArICAgICAgICAgICAgIHBy
X2VycigiJXM6IGNvdWxkIG5vdCBnZXQgcmVnIHByb3BlcnR5XG4iLCBucC0+bmFtZSk7DQo+ID4g
PiArICAgICAgICAgICAgIHJldHVybjsNCj4gPiA+ICsgICAgIH0NCj4gPiA+ICsNCj4gPiA+ICsg
ICAgIC8qIGdldCB0aGUgaW5wdXQgY2xvY2sgc291cmNlIGNvdW50ICovDQo+ID4gPiArICAgICBj
b3VudCA9IG9mX3Byb3BlcnR5X2NvdW50X3N0cmluZ3MobnAsICJjbG9jay1uYW1lcyIpOw0KPiA+
ID4gKyAgICAgaWYgKGNvdW50IDwgMCkgew0KPiA+ID4gKyAgICAgICAgICAgICBwcl9lcnIoIiVz
OiBnZXQgY2xvY2sgY291bnQgZXJyb3JcbiIsIG5wLT5uYW1lKTsNCj4gPiA+ICsgICAgICAgICAg
ICAgcmV0dXJuOw0KPiA+ID4gKyAgICAgfQ0KPiA+ID4gKyAgICAgcGFyZW50X25hbWVzID0ga3ph
bGxvYygoc2l6ZW9mKGNoYXIgKikgKiBjb3VudCksIEdGUF9LRVJORUwpOw0KPiA+ID4gKyAgICAg
aWYgKCFwYXJlbnRfbmFtZXMpIHsNCj4gPiA+ICsgICAgICAgICAgICAgcHJfZXJyKCIlczogY291
bGQgbm90IGFsbG9jYXRlIHBhcmVudF9uYW1lc1xuIiwNCj4gX19mdW5jX18pOw0KPiA+ID4gKyAg
ICAgICAgICAgICByZXR1cm47DQo+ID4gPiArICAgICB9DQo+ID4gPiArDQo+ID4gPiArICAgICBm
b3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykNCj4gPiA+ICsgICAgICAgICAgICAgcGFyZW50X25h
bWVzW2ldID0gb2ZfY2xrX2dldF9wYXJlbnRfbmFtZShucCwgaSk7DQo+ID4gPiArDQo+ID4gPiAr
ICAgICBjbXV4X2NsayA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBjbXV4X2NsayksIEdGUF9LRVJO
RUwpOw0KPiA+ID4gKyAgICAgaWYgKCFjbXV4X2Nsaykgew0KPiA+ID4gKyAgICAgICAgICAgICBw
cl9lcnIoIiVzOiBjb3VsZCBub3QgYWxsb2NhdGUgY211eF9jbGtcbiIsIF9fZnVuY19fKTsNCj4g
PiA+ICsgICAgICAgICAgICAgZ290byBlcnJfbmFtZTsNCj4gPiA+ICsgICAgIH0NCj4gPiA+ICsg
ICAgIGNtdXhfY2xrLT5yZWcgPSBiYXNlICsgb2Zmc2V0Ow0KPiA+ID4gKw0KPiA+ID4gKyAgICAg
bm9kZSA9IG9mX2ZpbmRfY29tcGF0aWJsZV9ub2RlKE5VTEwsIE5VTEwsICJmc2wscDQwODAtDQo+
IGNsb2NrZ2VuIik7DQo+ID4gPiArICAgICBpZiAobm9kZSAmJiAob2Zmc2V0ID49IDB4ODApKQ0K
PiA+ID4gKyAgICAgICAgICAgICBjbXV4X2Nsay0+ZmxhZ3MgPSBDTEtTRUxfQURKVVNUOw0KPiA+
ID4gKw0KPiA+ID4gKyAgICAgcmMgPSBvZl9wcm9wZXJ0eV9yZWFkX3N0cmluZ19pbmRleChucCwg
ImNsb2NrLW91dHB1dC1uYW1lcyIsDQo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgMCwgJmNs
a19uYW1lKTsNCj4gPiA+ICsgICAgIGlmIChyYykgew0KPiA+ID4gKyAgICAgICAgICAgICBwcl9l
cnIoIiVzOiByZWFkIGNsb2NrIG5hbWVzIGVycm9yXG4iLCBucC0+bmFtZSk7DQo+ID4gPiArICAg
ICAgICAgICAgIGdvdG8gZXJyX2NsazsNCj4gPiA+ICsgICAgIH0NCj4gPiA+ICsNCj4gPiA+ICsg
ICAgIGluaXQubmFtZSA9IGNsa19uYW1lOw0KPiA+ID4gKyAgICAgaW5pdC5vcHMgPSAmY211eF9v
cHM7DQo+ID4gPiArICAgICBpbml0LnBhcmVudF9uYW1lcyA9IHBhcmVudF9uYW1lczsNCj4gPiA+
ICsgICAgIGluaXQubnVtX3BhcmVudHMgPSBjb3VudDsNCj4gPiA+ICsgICAgIGluaXQuZmxhZ3Mg
PSAwOw0KPiA+ID4gKyAgICAgY211eF9jbGstPmh3LmluaXQgPSAmaW5pdDsNCj4gPiA+ICsNCj4g
PiA+ICsgICAgIGNsayA9IGNsa19yZWdpc3RlcihOVUxMLCAmY211eF9jbGstPmh3KTsNCj4gPiA+
ICsgICAgIGlmIChJU19FUlIoY2xrKSkgew0KPiA+ID4gKyAgICAgICAgICAgICBwcl9lcnIoIiVz
OiBjb3VsZCBub3QgcmVnaXN0ZXIgY2xvY2tcbiIsIGNsa19uYW1lKTsNCj4gPiA+ICsgICAgICAg
ICAgICAgZ290byBlcnJfY2xrOw0KPiA+ID4gKyAgICAgfQ0KPiA+ID4gKw0KPiA+ID4gKyAgICAg
cmMgPSBvZl9jbGtfYWRkX3Byb3ZpZGVyKG5wLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7
DQo+ID4gPiArICAgICBpZiAocmMpIHsNCj4gPiA+ICsgICAgICAgICAgICAgcHJfZXJyKCJDb3Vs
ZCBub3QgcmVnaXN0ZXIgY2xvY2sgcHJvdmlkZXIgZm9yDQo+IG5vZGU6JXNcbiIsDQo+ID4gPiAr
ICAgICAgICAgICAgICAgICAgICAgIG5wLT5uYW1lKTsNCj4gPiA+ICsgICAgICAgICAgICAgZ290
byBlcnJfY2xrOw0KPiA+ID4gKyAgICAgfQ0KPiA+ID4gKyAgICAgZ290byBlcnJfbmFtZTsNCj4g
PiA+ICsNCj4gPiA+ICtlcnJfY2xrOg0KPiA+ID4gKyAgICAga2ZyZWUoY211eF9jbGspOw0KPiA+
ID4gK2Vycl9uYW1lOg0KPiA+ID4gKyAgICAgLyogZnJlZSAqX25hbWVzIGJlY2F1c2UgdGhleSBh
cmUgcmVhbGxvY2F0ZWQgd2hlbiByZWdpc3RlcmVkICovDQo+ID4gPiArICAgICBrZnJlZShwYXJl
bnRfbmFtZXMpOw0KPiA+ID4gK30NCj4gPiA+ICsNCj4gPiA+ICtzdGF0aWMgdm9pZCBfX2luaXQg
Y29yZV9wbGxfaW5pdChzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wKSB7DQo+ID4gPiArICAgICB1MzIg
b2Zmc2V0LCBtdWx0Ow0KPiA+ID4gKyAgICAgaW50IGksIHJjLCBjb3VudDsNCj4gPiA+ICsgICAg
IGNvbnN0IGNoYXIgKmNsa19uYW1lLCAqcGFyZW50X25hbWU7DQo+ID4gPiArICAgICBzdHJ1Y3Qg
Y2xrX29uZWNlbGxfZGF0YSAqb25lY2VsbF9kYXRhOw0KPiA+ID4gKyAgICAgc3RydWN0IGNsayAg
ICAgICoqc3ViY2xrczsNCj4gPiA+ICsNCj4gPiA+ICsgICAgIHJjID0gb2ZfcHJvcGVydHlfcmVh
ZF91MzIobnAsICJyZWciLCAmb2Zmc2V0KTsNCj4gPiA+ICsgICAgIGlmIChyYykgew0KPiA+ID4g
KyAgICAgICAgICAgICBwcl9lcnIoIiVzOiBjb3VsZCBub3QgZ2V0IHJlZyBwcm9wZXJ0eVxuIiwg
bnAtPm5hbWUpOw0KPiA+ID4gKyAgICAgICAgICAgICByZXR1cm47DQo+ID4gPiArICAgICB9DQo+
ID4gPiArDQo+ID4gPiArICAgICAvKiBnZXQgdGhlIG11bHRpcGxlIG9mIFBMTCAqLw0KPiA+ID4g
KyAgICAgbXVsdCA9IGlvcmVhZDMyYmUoYmFzZSArIG9mZnNldCk7DQo+ID4gPiArDQo+ID4gPiAr
ICAgICAvKiBjaGVjayBpZiB0aGlzIFBMTCBpcyBkaXNhYmxlZCAqLw0KPiA+ID4gKyAgICAgaWYg
KG11bHQgJiBQTExfS0lMTCkgew0KPiA+ID4gKyAgICAgICAgICAgICBwcl9kZWJ1ZygiUExMOiVz
IGlzIGRpc2FibGVkXG4iLCBucC0+bmFtZSk7DQo+ID4gPiArICAgICAgICAgICAgIHJldHVybjsN
Cj4gPiA+ICsgICAgIH0NCj4gPiA+ICsgICAgIG11bHQgPSAobXVsdCA+PiAxKSAmIDB4M2Y7DQo+
ID4gPiArDQo+ID4gPiArICAgICBwYXJlbnRfbmFtZSA9IG9mX2Nsa19nZXRfcGFyZW50X25hbWUo
bnAsIDApOw0KPiA+ID4gKyAgICAgaWYgKCFwYXJlbnRfbmFtZSkgew0KPiA+ID4gKyAgICAgICAg
ICAgICBwcl9lcnIoIlBMTDogJXMgbXVzdCBoYXZlIGEgcGFyZW50XG4iLCBucC0+bmFtZSk7DQo+
ID4gPiArICAgICAgICAgICAgIHJldHVybjsNCj4gPiA+ICsgICAgIH0NCj4gPiA+ICsNCj4gPiA+
ICsgICAgIGNvdW50ID0gb2ZfcHJvcGVydHlfY291bnRfc3RyaW5ncyhucCwgImNsb2NrLW91dHB1
dC1uYW1lcyIpOw0KPiA+ID4gKyAgICAgaWYgKGNvdW50IDwgMCB8fCBjb3VudCA+IDQpIHsNCj4g
PiA+ICsgICAgICAgICAgICAgcHJfZXJyKCIlczogY2xvY2sgaXMgbm90IHN1cHBvcnRlZFxuIiwg
bnAtPm5hbWUpOw0KPiA+ID4gKyAgICAgICAgICAgICByZXR1cm47DQo+ID4gPiArICAgICB9DQo+
ID4gPiArDQo+ID4gPiArICAgICAvKiBvdXRwdXQgY2xvY2sgbnVtYmVyIHBlciBQTEwgKi8NCj4g
PiA+ICsgICAgIGNsb2Nrc19wZXJfcGxsID0gY291bnQ7DQo+ID4gPiArDQo+ID4gPiArICAgICBz
dWJjbGtzID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IGNsayAqKSAqIGNvdW50LCBHRlBfS0VSTkVM
KTsNCj4gPiA+ICsgICAgIGlmICghc3ViY2xrcykgew0KPiA+ID4gKyAgICAgICAgICAgICBwcl9l
cnIoIiVzOiBjb3VsZCBub3QgYWxsb2NhdGUgc3ViY2xrc1xuIiwgX19mdW5jX18pOw0KPiA+ID4g
KyAgICAgICAgICAgICByZXR1cm47DQo+ID4gPiArICAgICB9DQo+ID4gPiArDQo+ID4gPiArICAg
ICBvbmVjZWxsX2RhdGEgPSBremFsbG9jKHNpemVvZihzdHJ1Y3QgY2xrX29uZWNlbGxfZGF0YSks
DQo+IEdGUF9LRVJORUwpOw0KPiA+ID4gKyAgICAgaWYgKCFvbmVjZWxsX2RhdGEpIHsNCj4gPiA+
ICsgICAgICAgICAgICAgcHJfZXJyKCIlczogY291bGQgbm90IGFsbG9jYXRlIG9uZWNlbGxfZGF0
YVxuIiwNCj4gX19mdW5jX18pOw0KPiA+ID4gKyAgICAgICAgICAgICBnb3RvIGVycl9jbGtzOw0K
PiA+ID4gKyAgICAgfQ0KPiA+ID4gKw0KPiA+ID4gKyAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50
OyBpKyspIHsNCj4gPiA+ICsgICAgICAgICAgICAgcmMgPSBvZl9wcm9wZXJ0eV9yZWFkX3N0cmlu
Z19pbmRleChucCwgImNsb2NrLW91dHB1dC0NCj4gbmFtZXMiLA0KPiA+ID4gKyAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgaSwgJmNsa19uYW1lKTsNCj4gPiA+ICsgICAgICAgICAgICAgaWYg
KHJjKSB7DQo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgcHJfZXJyKCIlczogY291bGQgbm90
IGdldCBjbG9jayBuYW1lc1xuIiwgbnAtDQo+ID5uYW1lKTsNCj4gPiA+ICsgICAgICAgICAgICAg
ICAgICAgICBnb3RvIGVycl9jZWxsOw0KPiA+ID4gKyAgICAgICAgICAgICB9DQo+ID4gPiArDQo+
ID4gPiArICAgICAgICAgICAgIC8qDQo+ID4gPiArICAgICAgICAgICAgICAqIHdoZW4gY291bnQg
PT0gNCwgdGhlcmUgYXJlIDQgb3V0cHV0IGNsb2NrczoNCj4gPiA+ICsgICAgICAgICAgICAgICog
LzEsIC8yLCAvMywgLzQgcmVzcGVjdGl2ZWx5DQo+ID4gPiArICAgICAgICAgICAgICAqIHdoZW4g
Y291bnQgPCA0LCB0aGVyZSBhcmUgYXQgbGVhc3QgMiBvdXRwdXQgY2xvY2tzOg0KPiA+ID4gKyAg
ICAgICAgICAgICAgKiAvMSwgLzIsICgvNCwgaWYgY291bnQgPT0gMykgcmVzcGVjdGl2ZWx5Lg0K
PiA+ID4gKyAgICAgICAgICAgICAgKi8NCj4gPiA+ICsgICAgICAgICAgICAgaWYgKGNvdW50ID09
IDQpDQo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgc3ViY2xrc1tpXSA9IGNsa19yZWdpc3Rl
cl9maXhlZF9mYWN0b3IoTlVMTCwNCj4gY2xrX25hbWUsDQo+ID4gPiArICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF9uYW1lLCAwLCBtdWx0LCAxICsgaSk7DQo+ID4g
PiArICAgICAgICAgICAgIGVsc2UNCj4gPiA+ICsNCj4gPiA+ICsgICAgICAgICAgICAgICAgICAg
ICBzdWJjbGtzW2ldID0gY2xrX3JlZ2lzdGVyX2ZpeGVkX2ZhY3RvcihOVUxMLA0KPiBjbGtfbmFt
ZSwNCj4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50X25h
bWUsIDAsIG11bHQsIDEgPDwgaSk7DQo+ID4gPiArDQo+ID4gPiArICAgICAgICAgICAgIGlmIChJ
U19FUlIoc3ViY2xrc1tpXSkpIHsNCj4gPiA+ICsgICAgICAgICAgICAgICAgICAgICBwcl9lcnIo
IiVzOiBjb3VsZCBub3QgcmVnaXN0ZXIgY2xvY2tcbiIsDQo+IGNsa19uYW1lKTsNCj4gPiA+ICsg
ICAgICAgICAgICAgICAgICAgICBnb3RvIGVycl9jZWxsOw0KPiA+ID4gKyAgICAgICAgICAgICB9
DQo+ID4gPiArICAgICB9DQo+ID4gPiArDQo+ID4gPiArICAgICBvbmVjZWxsX2RhdGEtPmNsa3Mg
PSBzdWJjbGtzOw0KPiA+ID4gKyAgICAgb25lY2VsbF9kYXRhLT5jbGtfbnVtID0gY291bnQ7DQo+
ID4gPiArDQo+ID4gPiArICAgICByYyA9IG9mX2Nsa19hZGRfcHJvdmlkZXIobnAsIG9mX2Nsa19z
cmNfb25lY2VsbF9nZXQsDQo+IG9uZWNlbGxfZGF0YSk7DQo+ID4gPiArICAgICBpZiAocmMpIHsN
Cj4gPiA+ICsgICAgICAgICAgICAgcHJfZXJyKCJDb3VsZCBub3QgcmVnaXN0ZXIgY2xrIHByb3Zp
ZGVyIGZvciBub2RlOiVzXG4iLA0KPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICBucC0+bmFt
ZSk7DQo+ID4gPiArICAgICAgICAgICAgIGdvdG8gZXJyX2NlbGw7DQo+ID4gPiArICAgICB9DQo+
ID4gPiArDQo+ID4gPiArICAgICByZXR1cm47DQo+ID4gPiArZXJyX2NlbGw6DQo+ID4gPiArICAg
ICBrZnJlZShvbmVjZWxsX2RhdGEpOw0KPiA+ID4gK2Vycl9jbGtzOg0KPiA+ID4gKyAgICAga2Zy
ZWUoc3ViY2xrcyk7DQo+ID4gPiArfQ0KPiA+ID4gKw0KPiA+ID4gK3N0YXRpYyBjb25zdCBzdHJ1
Y3Qgb2ZfZGV2aWNlX2lkIGNsa19tYXRjaFtdIF9faW5pdGNvbnN0ID0gew0KPiA+ID4gKyAgICAg
eyAuY29tcGF0aWJsZSA9ICJmaXhlZC1jbG9jayIsIC5kYXRhID0gb2ZfZml4ZWRfY2xrX3NldHVw
LCB9LA0KPiA+ID4gKyAgICAgeyAuY29tcGF0aWJsZSA9ICJmc2wsY29yZS1wbGwtY2xvY2siLCAu
ZGF0YSA9IGNvcmVfcGxsX2luaXQsIH0sDQo+ID4gPiArICAgICB7IC5jb21wYXRpYmxlID0gImZz
bCxjb3JlLW11eC1jbG9jayIsIC5kYXRhID0gY29yZV9tdXhfaW5pdCwgfSwNCj4gPiA+ICsgICAg
IHt9DQo+ID4gPiArfTsNCj4gPiA+ICsNCj4gPiA+ICtzdGF0aWMgaW50IF9faW5pdCBwcGNfY29y
ZW5ldF9jbGtfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gew0KPiA+ID4g
KyAgICAgc3RydWN0IGRldmljZV9ub2RlICpucDsNCj4gPiA+ICsNCj4gPiA+ICsgICAgIG5wID0g
cGRldi0+ZGV2Lm9mX25vZGU7DQo+ID4gPiArICAgICBiYXNlID0gb2ZfaW9tYXAobnAsIDApOw0K
PiA+ID4gKyAgICAgaWYgKCFiYXNlKSB7DQo+ID4gPiArICAgICAgICAgICAgIGRldl9lcnIoJnBk
ZXYtPmRldiwgImlvbWFwIGVycm9yXG4iKTsNCj4gPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1F
Tk9NRU07DQo+ID4gPiArICAgICB9DQo+ID4gPiArICAgICBvZl9jbGtfaW5pdChjbGtfbWF0Y2gp
Ow0KPiA+ID4gKw0KPiA+ID4gKyAgICAgcmV0dXJuIDA7DQo+ID4gPiArfQ0KPiA+ID4gKw0KPiA+
ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHBwY19jbGtfaWRzW10gX19pbml0
Y29uc3QgPSB7DQo+ID4gPiArICAgICB7IC5jb21wYXRpYmxlID0gImZzbCxxb3JpcS1jbG9ja2dl
bi0xLjAiLCB9LA0KPiA+ID4gKyAgICAgeyAuY29tcGF0aWJsZSA9ICJmc2wscW9yaXEtY2xvY2tn
ZW4tMiIsIH0sDQo+ID4gPiArICAgICB7fQ0KPiA+ID4gK307DQo+ID4gPiArDQo+ID4gPiArc3Rh
dGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgcHBjX2NvcmVuZXRfY2xrX2RyaXZlciA9IHsNCj4g
PiA+ICsgICAgIC5kcml2ZXIgPSB7DQo+ID4gPiArICAgICAgICAgICAgIC5uYW1lID0gInBwY19j
b3JlbmV0X2Nsb2NrIiwNCj4gPiA+ICsgICAgICAgICAgICAgLm93bmVyID0gVEhJU19NT0RVTEUs
DQo+ID4gPiArICAgICAgICAgICAgIC5vZl9tYXRjaF90YWJsZSA9IHBwY19jbGtfaWRzLA0KPiA+
ID4gKyAgICAgfSwNCj4gPiA+ICsgICAgIC5wcm9iZSA9IHBwY19jb3JlbmV0X2Nsa19wcm9iZSwg
fTsNCj4gPiA+ICsNCj4gPiA+ICtzdGF0aWMgaW50IF9faW5pdCBwcGNfY29yZW5ldF9jbGtfaW5p
dCh2b2lkKSB7DQo+ID4gPiArICAgICByZXR1cm4gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZw
cGNfY29yZW5ldF9jbGtfZHJpdmVyKTsNCj4gPiA+ICt9DQo+ID4gPiArc3Vic3lzX2luaXRjYWxs
KHBwY19jb3JlbmV0X2Nsa19pbml0KTsNCj4gPiA+IC0tDQo+ID4gPiAxLjguMA0KDQo=
^ permalink raw reply
* RE: [PATCH v2] of/base: release the node correctly in of_parse_phandle_with_args()
From: Tang Yuantian-B29983 @ 2013-04-17 2:44 UTC (permalink / raw)
To: Timur Tabi
Cc: devicetree-discuss, linuxppc-dev@lists.ozlabs.org, lkml,
Rob Herring
In-Reply-To: <CAOZdJXW8qKccGKic3R4o1aqJdbfHcBoAp62B4HPFnF=sUAEvuQ@mail.gmail.com>
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBUaW11ciBUYWJpIFttYWlsdG86
dGltdXJAdGFiaS5vcmddDQo+IFNlbnQ6IDIwMTPE6jTUwjE2yNUgMTk6MzcNCj4gVG86IFRhbmcg
WXVhbnRpYW4tQjI5OTgzDQo+IENjOiBHcmFudCBMaWtlbHk7IGRldmljZXRyZWUtZGlzY3Vzczsg
bGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IGxrbWw7DQo+IFJvYiBIZXJyaW5nDQo+IFN1
YmplY3Q6IFJlOiBbUEFUQ0ggdjJdIG9mL2Jhc2U6IHJlbGVhc2UgdGhlIG5vZGUgY29ycmVjdGx5
IGluDQo+IG9mX3BhcnNlX3BoYW5kbGVfd2l0aF9hcmdzKCkNCj4gDQo+IE9uIFR1ZSwgQXByIDks
IDIwMTMgYXQgMTA6MzYgUE0sICA8WXVhbnRpYW4uVGFuZ0BmcmVlc2NhbGUuY29tPiB3cm90ZToN
Cj4gPg0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIC8qIEZvdW5kIGl0ISByZXR1cm4gc3Vj
Y2VzcyAqLw0KPiANCj4gSSdtIHByZXR0eSBzdXJlIHRoaXMgY29tbWVudCBpcyBpbiB0aGUgd3Jv
bmcgcGxhY2UuDQoNCkl0IGlzIG5vdCBwZXJmZWN0LCBidXQgYWNjZXB0YWJsZS4NCg0KLVl1YW50
aWFuDQoNCg==
^ 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